I have a resturant db and I need to total up the total value of all the items sold individually. So if I sold a hamburger that has a base price of $10.00 with bacon which costs $1.00 and a hambuger(again $10.00) with avacado that costs $0.50 I need to get $21.50 returned. My invoice table looks like this:
invoice_num item_num price item_id parent_item_id
111 hmbg 10.00 guid_1 ''
111 bacn 1.00 guid_2 guid_2
112 hmbg 10.00 guid_3 ''
112 avcd 0.50 guid_4 guid_3
I can get the sum of all the parent items like this:
SELECT item_num, SUM(price) FROM invoices WHERE parent_item_id = ''
it is the adding of the toppings that is confusing me. I feel like I need to add a subquery in the SUM but I'm not sure how to go about doing it and referencing the original query to use the item_id.
SELECT item_num, sum(i.price) + sum(nvl(x.ingred_price,0))
FROM invoices i
LEFT OUTER JOIN
(SELECT parent_item_id
, sum(price) ingred_price
FROM invoices
WHERE parent_item_id IS NOT NULL
GROUP BY parent_item_id) x
ON x.parent_item_id = i.item_id
WHERE i.parent_item_id IS NULL
GROUP BY item_num
Here's a SQL Fiddle that proves the above code works. I used Oracle, but you should be able to adapt it to whatever DB you are using.
Assumption: You don't have more than one level in a parent child relationship. E.g. A can have a child B, but B won't have any other children.
Not clear based on your question (see my comment) but as I understand it a simple group by will give you what you want. If not please explain (in the original question) why does this query does not work --- what is it missing from your requirements?
SELECT item_num, SUM(price)
FROM invoices
GROUP BY item_num
Hard to say, but looks like you need recursive cte.
Here's example for PostgreSQL:
with recursive cte as (
select
t.invoice_num, t.price, t.item_id, t.item_num
from Table1 as t
where t.parent_item_id is null
union all
select
t.invoice_num, t.price, t.item_id, c.item_num
from Table1 as t
inner join cte as c on c.item_id = t.parent_item_id
)
select invoice_num, item_num, sum(price)
from cte
group by invoice_num, item_num
sql fiddle demo
I've used null for empty parent_item_id (it's better solution than using empty strings), but you can change this to ''.
Related
I am trying to query the original source which contain totals from a category (in this case Vehicles) into the second table.
Motorcycle
Bicycle
Car
1
3
2
Desired Output:
Vehicle
Quantity
Bicycle
3
Car
2
Motorcycle
1
Additionally, I need that the Quantity is sorted in descending order like showing above.
So far I have tried to do an Unpivot, but there is a syntax error in the Unpivot function. Is there another way to reach out the same results?
My code so far:
SELECT Vehicle_Name
FROM
(
SELECT [Motorcycle], [Bycycle], [Car] from Data
) as Source
UNPIVOT
(
Vehicle FOR Vehicle_Name IN ([Motorcycle], [Bycycle], [Car])
) as Unpvt
Edit: Added sort requirement.
You can use CROSS APPLY here too
select vehicle, amnt
from test
cross apply(
VALUES('motorcycle', motorcycle)
,('bicycle', bicycle)
,('car', car)) x (vehicle, amnt)
order by amnt desc
Fiddle here
Try this
with data1 as
(
Select * from data)
Select * From
(
Select 'motorcycle' as "Vehicle", motorcycle as quantity from data1
union all
Select 'bicycle' , bicycle from data1
union all
Select 'car', car from data1
) order by quantity desc;
Since we don't know what DBMS, here's a way that'd work in the one I use the most.
SELECT *
FROM (SELECT map_from_entries(
ARRAY[('Motorcycle', Motorcycle),
('Bicycle', Bicycle),
('Car', Car)])
FROM Source) AS t1(type_quant)
CROSS JOIN UNNEST(type_quant) AS t2(Vehicle, Quantity)
ORDER BY Quantity DESC
-Trino
I have two tables i'm working with:
comporder(quantity,cod(Fk on cod(product),cod_ship);
product(cod(Pk),price);
I need to produce a query that will give me the sum of the prices of the products that are in the comporder table for each cod_ship;
I came up with this query:
SELECT sum(p.price),c.cod_ship
FROM product as p JOIN comporder as c
ON(p.cod=c.cod)
GROUP BY c.cod_ship;
However I am not allowed to use the GROUP BY function and I can't seem to have the price where the quanity is above one.
For exampe if in my comporder table I have:
quantity cod cod_ship
2 "1234567890" 27
3 "1234567890" 28
2 "7894561230" 28
1 "5678324515" 28
4 "1234567890" 27
1 "1234567890" 27
And if in my product table I have:
cod price
"1234567890" 20.00
"7894561230" 19.99
"5678324515" 25.99
If I apply my query the result will be:
sum cod_ship
60 27
65.979 28
When te actual result should be, based on the quantity of the products in the table comporder:
sum // cod_ship//
140 // 27//
125,97 //28//
So I can't seem to figure out how to get the sum also based on the quantity of the product and witouth the GROUP BY function, I should just show the sum as "output", can somebody help me out understand how can I do it?
REPLYING TO COMMENTS:
I cannot use group by due to an assignment.
I am using PostgreSQL 12.1
As requested by the OP in the comments here is a solution using GROUP BY:
SELECT SUM(price * quantity) as sum, cod_ship FROM comporders
INNER JOIN products ON products.cod = comporders.cod
GROUP BY cod_ship;
Edit:
Here is the solution without GROUP BY:
SELECT DISTINCT
(
SELECT SUM(price * quantity)
FROM products
INNER JOIN comporders ON products.cod = comporders.cod
WHERE cod_ship = results.cod_ship
) AS sum,
cod_ship
FROM comporders AS results;
It works by first selecting a unique list of cod_ship ids (what we previously grouped the query by).
Then we execute a subquery using the cod_ship id to calculate the sum for each column. We use the table alias results in order to reference the values in the parent query of the subquery.
SQL Fiddle Link
You can do aggregation in subselect like this:
SELECT (
SELECT SUM(p.price)
FROM product AS p
WHERE p.cod = c.cod
) AS price, c.cod_ship
FROM comporder AS c
Sorry if the title seems confusing, it was the best I could come up with.
I can work with both excel(Dax since its a power query) and sql:
I have a situation where there are two product types being purchased, Type_A and Type_B.
I want to calculate a count of how many unique Loc_ID have purchased a "Type_A" Product type, AFTER purchasing a "Type_B" Product type.
From my example there are a total of 3 unique Loc_ID which would fall in this filter: Loc_01, Loc_02, and Loc_04
Any help is greatly appreciated
Try this (it works good if each loc_id purchased both type of products as in your example.
select count(*)
from
(select loc_id , max(date_purchased) dt
from table t where product_type = 'type_a'
group by loc_id) a,
(select loc_id , max(date_purchased) dt
from table t where product_type = 'type_b'
group by loc_id) b
where a.loc_id=b.loc_id and a.dt>b.dt;
This will work even if certain loc_id did not purchase both type of products
Try this:-
Select count(a.loc_id) as cnt_locations
from
your_table_name a
inner join
(
Select a.loc_id,b.date_purchased,b.Product_type
from
(
Select loc_id, min(date_purchased) as date_purchased
from
your_table_name
group by loc_id
) a
inner join
your_table_name b
on a.loc_id=b.loc_id and a.date_purchased =b.date_purchased
where Product_type ='Type_B'
) b
on
a.loc_id=b.loc_id
where a.date_purchased >b.date_purchased and a.Product_type ='Type_A'
this query works fine for me.
SELECT (SUM(AveragePrice)/COUNT(1)) AS AveragePrice, SUM(ItemsSold) AS ItemSold ,(SUM(AveragePrice * ItemsSold)) AS TotalSale FROM dbo.tbl_ProductSales
WHERE ProductID IN ( SELECT ProductID FROM tbl_ProductPostions WHERE tbl_ProductPostions.SearchID=3 AND SaleDate='2012-02-02 00:00:00.000')
GROUP BY SaleDate
and resuts like this
AveragePrice | ItemSold | TotalSale
10 | 2 | 2000
but when i embed this query like this
SELECT * ,(SELECT (SUM(AveragePrice)/COUNT(1)) AS AveragePrice, SUM(ItemsSold) AS ItemSold ,(SUM(AveragePrice * ItemsSold)) AS TotalSale FROM dbo.tbl_ProductSales
WHERE ProductID IN ( SELECT ProductID FROM tbl_ProductPostions WHERE tbl_ProductPostions.SearchID=tbl_SearchParameters.SearchID AND SaleDate='2012-02-02 00:00:00.000')
GROUP BY SaleDate )
FROM tbl_SearchParameters
i got an error like this.
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
i know i am crossing the limits but is there any alternate way to do this.
i know the function can be created to do this task. but is essential to create
three function separately to compute this these aggregate Average Price,Item Sold,Total Sale?
while i am sure a single query can compute three aggregate for me ?
can any body suggest me proper solution ? i just want to get ride of creating three functions separately for these aggregate respectively.
Regards.
You can use APPLY() operator
SELECT *
FROM tbl_SearchParameters p
CROSS APPLY (
SELECT SUM(AveragePrice/COUNT(1)) AS AveragePrice,
SUM(ItemsSold) AS ItemSold,
SUM(AveragePrice * ItemsSold) AS TotalSale
FROM dbo.tbl_ProductSales
WHERE ProductID IN (SELECT ProductID
FROM tbl_ProductPostions
WHERE tbl_ProductPostions.SearchID = p.SearchID
AND SaleDate='2012-02-02 00:00:00.000')
GROUP BY SaleDate
) o
Try to remove the second SELECT like:
SELECT * ,(SUM(AveragePrice)/COUNT(1)) AS AveragePrice,
SUM(ItemsSold) AS ItemSold ,
(SUM(AveragePrice * ItemsSold)) AS TotalSale
FROM dbo.tbl_ProductSales
WHERE ProductID IN (SELECT ProductID
FROM tbl_ProductPostions
WHERE tbl_ProductPostions.SearchID=tbl_SearchParameters.SearchID
AND SaleDate='2012-02-02 00:00:00.000')
GROUP BY SaleDate )
FROM tbl_SearchParameters
this statement will generate a 4 column table:
SELECT shipped.badguy AS badguy, shipped.sdate AS LineDate,
'Delivery' AS Legend, -price*quantity AS amount
FROM product JOIN shipped ON (product.id = shipped.product)
UNION
SELECT receipt.badguy, receipt.rdate,notes, amount
FROM receipt
how do i get the total sum of the 4th of column of what the above generates?
I like to use subqueries for everything.
SELECT SUM(results.amount)
FROM
(
SELECT -price*quantity AS amount
FROM product JOIN shipped ON (product.id = shipped.product)
UNION
SELECT amount
FROM
...
) results
SUM(-price*quantity)
huh?
Try
sum(price*quantity)
or combine both query as
SELECT badguy,rdate,notes,SUM(AMOUNT) FROM(
SELECT shipped.badguy AS badguy, shipped.sdate AS LineDate,
'Delivery' AS Legend, -price*quantity AS amount
FROM product JOIN shipped ON (product.id = shipped.product)
UNION
SELECT receipt.badguy, receipt.rdate,notes, amount
FROM) A
Wrap your query in another query, where the outer query just gets the sum you want. This makes your query a subquery.
SELECT SUM(amount) FROM (
SELECT shipped.badguy AS badguy, shipped.sdate AS LineDate,
'Delivery' AS Legend, -price*quantity AS amount
FROM product JOIN shipped ON (product.id = shipped.product)
UNION
SELECT receipt.badguy, receipt.rdate,notes, amount
FROM <...>
)