I have a table structure similar to this:
id | order1_id | order1_type | order1_amount | order2_id | order2_type | order2_amount
------------------------------------------------------------------------------------------
1 1 3 4 1 4 5
2 2 1 1 1 3 2
3 1 4 4 2 2 1
I want to get the data like this:
order_id | order_type | order_amount
1 3 6
1 4 9
2 1 1
2 2 1
I want to group by type, and sum the order amounts. How can I do that ?
Thanks,
I'm going to use a union in a subquery to line the columns up, then group and sum on that.
Assuming you're stuck with this less-than-ideal table structure, you may want to create a view that represents the subquery below, then run the group by/sum against that view. I'm guessing such a view might be useful in more places than just this one query.
select t.order_id, t.order_type, sum(t.order_amount)
from (select order1_id as order_id, order1_type as order_type, order1_amount as order_amount
from orders
union all
select order2_id as order_id, order2_type as order_type, order2_amount as order_amount
from orders
union all
select order3_id as order_id, order3_type as order_type, order3_amount as order_amount
from orders
union all
select order4_id as order_id, order4_type as order_type, order4_amount as order_amount
from orders
union all
select order5_id as order_id, order5_type as order_type, order5_amount as order_amount
from orders) t
group by t.order_id, t.order_type
The easy way would be to use a view to untangle the table of questionable design, then group and sum on the view.
create view normalized_orders as
select order1_id as order_id,
order1_type as order_type,
order1_amount as order_amount
from your_table
union all
select order2_id as order_id,
order2_type as order_type,
order2_amount as order_amount
from your_table
Then you can do this:
select order_id, order_type, sum(order_amount)
from normalized_orders
group by order_id, order_type
order by order_id, order_type
Related
I am using mariadb and I have a table called links:
id | product_id | last_change
------------------------------
1 1 xxx
2 2 xxx
3 5 xxx
4 5 xxx
I want to find every object (3, 4 in this example) that occures more than once. Following this answer I tried:
SELECT product_id, COUNT(*) from links HAVING COUNT(*) > 1
But this results in the (adapted to this example) first row being shown and the total number of product_id occurrences:
product_id | COUNT(*)
---------------------
1 4
I wanted to achieve a list of all items occuring more than once:
id | product_id | last_change
------------------------------
3 5 xxx
4 5 xxx
An aggregation function without GROUP BY always results in only one row result as it aggregates all rows
So use a GROUP BY
SELECT product_id, COUNT(*) from links GROUP BY product_id HAVING COUNT(*) > 1
To see all entry with the count of the product_id , you can do following
SELECT l1.product_id , last_change , Count_
FROM links l1
JOIN (SELECT product_id, COUNT(*) as Count_ from links GROUP BY product_id HAVING COUNT(*) > 1) l2
ON l1.product_id = l2.product_id
Try below statement
select id, product_id, count(product_id)
from links
group by (product_id)
having count(product_id)> 1;
I'm running a query that selects details of orders, and I want to see only the orders that have gone through multiple stages. My data looks like:
id | order_id | action
1 100 1
2 100 2
3 100 4
4 101 1
5 102 2
6 103 1
7 103 2
So that only the rows for order_id 100 and 103 will be selected. This needs to be nested in a larger query.
You can use a subquery to get the orders that had multiple stages:
SELECT order_id
FROM your_table
GROUP BY order_id
HAVING COUNT(*)>1
then you can join this result back to your table:
SELECT o.*
FROM yourtable AS o INNER JOIN (
SELECT order_id
FROM your_table
GROUP BY order_id
HAVING COUNT(*)>1
) dup ON o.order_id = dup.order_id
Use group by with count and having
select *,count(order_id) as total from table
group by order_id
having total > 1
you can try this query:
select * from your_table
where ( select count(*) from your_table internal_table
where your_table .order_id = internal_table.order_id
) > 1
I have data as follows:
Product Quantity
A 3
B 2
This is data that as been previously rolled up at the product level. Assume there are only two columns as of now.
I want an output as follows:
Product Quantity
A 1
A 1
A 1
B 1
B 1
You could use a trick like this:
SELECT Product, 1 AS Quantity
FROM
Products INNER JOIN (
SELECT 1 AS q UNION ALL
SELECT 2 UNION ALL SELECT 2 UNION ALL
SELECT 3 UNION ALL SELECT 3 UNION ALL SELECT 3
) quantities
ON Products.Quantity = quantities.q
of course, this query is limited to a quantity of 3, but you can add more quantities to your subquery if they are of a limited amount.
I have a table of products sales
id product_id price_sold
1 1 500
2 1 300
3 2 100
4 3 200
5 3 100
I want to be able to sum the prices by different subsets of products, say: sum of prices per the group of proucts 1,2. and another calculation of sum of prices per the group of products 2,3, so the needed result will be:
group 1, 900
group 2, 400
Can you help with efficient and elegant way to do that?
Doing what you want is a bit challenging, because the groups overlap. You have two options. The first is to do conditional aggregation and put the results in columns:
select sum(case when product_id in (1, 2) then price_sold end) as group1,
sum(case when product_id in (2, 3) then price_sold end) as group2
from productsales ps;
To get the results on separate rows, you could then pivot this result. Or, you could do the calculation directly. For this to work, you need to construct a table describing the groups:
select pg.grpid, sum(ps.price_sold)
from productsales ps
join
(
select 1 as grpid, 1 as product_id
union all
select 1 as grpid, 2 as product_id
union all
select 2 as grpid, 2 as product_id
union all
select 2 as grpid, 3 as product_id
) pg on ps.product_id = pg.product_id
group by pg.grpid;
SQL Fiddle:
SELECT 'GROUP 1' AS `Group`, SUM(price_sold) AS PriceSum
FROM MyTable
WHERE product_id = 1 OR product_id = 2
UNION
SELECT 'GROUP 2', SUM(price_sold)
FROM MyTable
WHERE product_id = 2 OR product_id = 3
The result looks like:
I have a mysql table with a structure like this:
order_id - customer_name - customer_email_address
i need to do a query to search for records that have same customer_name OR same customer_email and show the result ordered by order_id groups (descending order).
Example:
Mysql table
order_id customer_name customer_email_address
1 pippo pippo#pippo.com
2 pippo pippo2#pippo2.com
3 pluto pluto#pluto.com
4 caio pippo#pippo.com
5 pippo4 pippo4#pippo4.com
6 pluto pluto22#pluto22.com
Result
6 pluto pluto22#pluto22.com
3 pluto pluto#pluto.com
4 caio pippo#pippo.com
1 pippo pippo#pippo.com
2 pippo pippo2#pippo2.com
Result 6 and 3 share the same customer_name
Result 4 and 1 share the same customer_email_address
Result 1 and 2 share the same customer_name
Order_id 5 is not in results because it has no duplicates.
Try this:
SELECT
order_id,
customer_name,
customer_email_address
FROM
my_table
WHERE
order_id IN (
SELECT
order_id
FROM
my_table
GROUP BY
customer_name
HAVING
COUNT(*)>1
UNION
SELECT
order_id,
FROM
my_table
GROUP BY
customer_email_address
HAVING
COUNT(*)>1
)
ORDER BY
customer_name,
customer_email_address,
order_id DESC