"Error near from" in UNION query - sql

I'm getting an error "error near FROM" in SQLite, however I couldn't find any faults in this query. What am I doing wrong?
Select
tbltrans2_temp.itemcode,
tbltrans2_temp.itemname,
Sum(tbltrans2_temp.qty) qty
From
tbltrans_temp Inner Join
tbltrans2_temp On tbltrans2_temp.transID = tbltrans_temp.transid
where
tbltrans_temp.saleDate='11/07/2013'
Group By
tbltrans2_temp.itemcode
UNION
Select
tbltrans2.itemcode,
tbltrans2.itemname,
Sum(tbltrans2.qty) qty,
From
tbltrans Inner Join
tbltrans2 On tbltrans2.transid = tbltrans.transid
where
tbltrans.saleDate='11/07/2013'
Group By
tbltrans2.itemcode

There is an extra , before the second FROM remove it:
Select
tbltrans2_temp.itemcode,
tbltrans2_temp.itemname,
Sum(tbltrans2_temp.qty) qty
From
tbltrans_temp Inner Join
tbltrans2_temp On tbltrans2_temp.transID = tbltrans_temp.transid
where
tbltrans_temp.saleDate='11/07/2013'
Group By
tbltrans2_temp.itemcode
UNION
Select
tbltrans2.itemcode,
tbltrans2.itemname,
Sum(tbltrans2.qty) qty, <<<<------------------- This
From
tbltrans Inner Join
tbltrans2 On tbltrans2.transid = tbltrans.transid
where
tbltrans.saleDate='11/07/2013'
Group By
tbltrans2.itemcode
Update
To get the sum of qty from both the table, put that query in a subquery and sum it in the outer one, you can also omit the sum in the inner query and only do it in the outer one:
SELECT
itemcode,
itemname,
SUM(qty) TotalQty
FROM
(
Select
tbltrans2_temp.itemcode,
tbltrans2_temp.itemname,
Sum(tbltrans2_temp.qty) qty
From
tbltrans_temp Inner Join
tbltrans2_temp On tbltrans2_temp.transID = tbltrans_temp.transid
where
tbltrans_temp.saleDate='11/07/2013'
Group By
tbltrans2_temp.itemcode
UNION
Select
tbltrans2.itemcode,
tbltrans2.itemname,
Sum(tbltrans2.qty) qty
From
tbltrans Inner Join
tbltrans2 On tbltrans2.transid = tbltrans.transid
where
tbltrans.saleDate='11/07/2013'
Group By
tbltrans2.itemcode
) t
GROUP BY itemcode, itemname;

Related

SUM all prices from table SQL

i have following SQL query which is summing tourist tax from selected period.
SELECT
BTR_DESCRIPTION AS TOURIST_TAX_NAME,
ISNULL(BREAG_TOURIST_TAX_PRICE,0) AS PRICE,
SUM(DATEDIFF(d, BRE_DATEFROM, BRE_DATETO)) AS QUANTITY,
ISNULL(BREAG_TOURIST_TAX_PRICE,0) * SUM(DATEDIFF(d, BRE_DATEFROM, BRE_DATETO)) AS FINAL_PRICE
FROM BOS_RESERVATION
LEFT OUTER JOIN BOS_RESADDGUEST ON BREAG_BRE_ID = BRE_ID
LEFT OUTER JOIN BOS_TAX_REASONS ON BTR_ID = BREAG_BTR_ID
WHERE BREAG_DATEFROM >= '2018-02-28' AND BREAG_DATETO <= '2018-03-31'
GROUP BY BTR_DESCRIPTION, BREAG_TOURIST_TAX_PRICE
Query result:
Now i want to sum all values from FINAL_PRICE row. So the result must be: 5,652
But i dont know how to do this. I tried with following SQL:
SUM(ISNULL(BREAG_TOURIST_TAX_PRICE,0) * SUM(DATEDIFF(d, BRE_DATEFROM, BRE_DATETO))) AS FINAL_PRICE_SUM
But this gives me error: Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
Can you please help me how to sum all values from FINAL_PRICE row?
Thanks!
You can do it like this:
WITH AggregatedTable as (SELECT
BTR_DESCRIPTION AS TOURIST_TAX_NAME,
ISNULL(BREAG_TOURIST_TAX_PRICE,0) AS PRICE,
SUM(DATEDIFF(d, BRE_DATEFROM, BRE_DATETO)) AS QUANTITY,
ISNULL(BREAG_TOURIST_TAX_PRICE,0) * SUM(DATEDIFF(d, BRE_DATEFROM, BRE_DATETO)) AS FINAL_PRICE
FROM BOS_RESERVATION
LEFT OUTER JOIN BOS_RESADDGUEST ON BREAG_BRE_ID = BRE_ID
LEFT OUTER JOIN BOS_TAX_REASONS ON BTR_ID = BREAG_BTR_ID
WHERE BREAG_DATEFROM >= '2018-02-28' AND BREAG_DATETO <= '2018-03-31'
GROUP BY BTR_DESCRIPTION, BREAG_TOURIST_TAX_PRICE)
Select at.*,
(SELECT SUM(FINAL_PRICE) from AggregatedTable)) as Total_FP
from AggregatedTable AS at
If you want the total final price, use a CTE or subquery:
WITH r as (
SELECT BTR_DESCRIPTION AS TOURIST_TAX_NAME,
COALESCE(BREAG_TOURIST_TAX_PRICE, 0) AS PRICE,
SUM(DATEDIFF(day, BRE_DATEFROM, BRE_DATETO)) AS QUANTITY,
COALESCE(BREAG_TOURIST_TAX_PRICE, 0) * SUM(DATEDIFF(day, BRE_DATEFROM, BRE_DATETO)) AS FINAL_PRICE
FROM BOS_RESERVATION LEFT OUTER JOIN
BOS_RESADDGUEST
ON BREAG_BRE_ID = BRE_ID LEFT OUTER JOIN
BOS_TAX_REASONS
ON BTR_ID = BREAG_BTR_ID
WHERE BREAG_DATEFROM >= '2018-02-28' AND BREAG_DATETO <= '2018-03-31'
GROUP BY BTR_DESCRIPTION, BREAG_TOURIST_TAX_PRICE
)
SELECT SUM(FINAL_PRICE)
FROM r;

Item rows duplicate and SUM for Total Expense

When the below query is executed the "TotalExpense" column duplicates to the number of rows that are present in the tblOrderProduct for a given SalesID.
SELECT ItemSales.OrderDate,tblExpense.DateOfExpense ,(Nz(SUM(tblOrderProduct.Quantity * tblOrderProduct.ConsumerPrice))) AS TotalSales, (Nz(SUM(tblExpense.Expense))) AS TotalExpense , (Nz(SUM(tblOrderProduct.Quantity * tblOrderProduct.ConsumerPrice)) - Nz(SUM(tblExpense.Expense)))AS Profit
FROM (ItemSales
LEFT JOIN tblOrderProduct ON ItemSales.SalesID = tblOrderProduct.SalesID)
LEFT JOIN tblExpense ON itemSales.OrderDate = tblExpense.DateOfExpense
GROUP BY ItemSales.OrderDate, tblExpense.DateOfExpense
ORDER BY ItemSales.OrderDate
UNION SELECT ItemSales.OrderDate, tblExpense.DateOfExpense, (Nz(SUM(tblOrderProduct.Quantity * tblOrderProduct.ConsumerPrice))) AS TotalSales, (Nz(SUM(tblExpense.Expense))) AS TotalExpense ,(Nz(SUM(tblOrderProduct.Quantity * tblOrderProduct.ConsumerPrice)) - Nz(SUM(tblExpense.Expense)))AS Profit
FROM (ItemSales
RIGHT JOIN tblExpense ON ItemSales.OrderDate = tblExpense.DateOfExpense)
LEFT JOIN tblOrderProduct ON ItemSales.SalesID = tblOrderProduct.SalesID
GROUP BY ItemSales.OrderDate,tblExpense.DateOfExpense
ORDER BY ItemSales.OrderDate
EDIT :-
Please see below for the result I get from the executed query:
The value highlighted in red only has expense worth 1000 for the given date, How ever the sales related to the same day has 22 rows of data hence the result is showing 22000
What is causing this duplication?
SELECT ItemSales.OrderDate,tblExpense.DateOfExpense ,(Nz(SUM(tblOrderProduct.Quantity * tblOrderProduct.ConsumerPrice))) AS TotalSales, (Nz(SUM(tblExpense.Expense))) AS TotalExpense , (Nz(SUM(tblOrderProduct.Quantity * tblOrderProduct.ConsumerPrice)) - Nz(SUM(tblExpense.Expense)))AS Profit
FROM (ItemSales
LEFT JOIN tblOrderProduct ON ItemSales.SalesID = tblOrderProduct.SalesID)
LEFT JOIN
( select DateOfExpense,sum(Expense) AS Expense FROM tblExpense Group by DateOfExpense)
tblExpense ON itemSales.OrderDate = tblExpense.DateOfExpense
GROUP BY ItemSales.OrderDate, tblExpense.DateOfExpense
ORDER BY ItemSales.OrderDate
UNION
SELECT ItemSales.OrderDate, tblExpense.DateOfExpense, (Nz(SUM(tblOrderProduct.Quantity * tblOrderProduct.ConsumerPrice))) AS TotalSales, (Nz(SUM(tblExpense.Expense))) AS TotalExpense ,(Nz(SUM(tblOrderProduct.Quantity * tblOrderProduct.ConsumerPrice)) - Nz(SUM(tblExpense.Expense)))AS Profit
FROM ItemSales
RIGHT JOIN
( select DateOfExpense,sum(Expense) AS Expense FROM tblExpense Group by DateOfExpense)
tblExpense ON ItemSales.OrderDate = tblExpense.DateOfExpense
LEFT JOIN tblOrderProduct ON ItemSales.SalesID = tblOrderProduct.SalesID
GROUP BY ItemSales.OrderDate,tblExpense.DateOfExpense
ORDER BY ItemSales.OrderDate

Complex Full Outer Join

Sigh ... can anyone help? In the SQL query below, the results I get are incorrect. There are three (3) labor records in [LaborDetail]
Hours / Cost
2.75 / 50.88
2.00 / 74.00
1.25 / 34.69
There are two (2) material records in [WorkOrderInventory]
Material Cost
42.75
35.94
The issue is that the query incorrectly returns the following:
sFunction cntWO sumLaborHours sumLaborCost sumMaterialCost
ROBOT HARNESS 1 12 319.14 236.07
What am I doing wrong in the query that is causing the sums to be multiplied? The correct values are sumLaborHours = 6, sumLaborCost = 159.57, and sumMaterialCost = 78.69. Thank you for your help.
SELECT CASE WHEN COALESCE(work_orders.location, Work_Orders_Archived.location) IS NULL
THEN '' ELSE COALESCE(work_orders.location, Work_Orders_Archived.location) END AS sFunction,
(SELECT COUNT(*)
FROM work_orders
FULL OUTER JOIN Work_Orders_Archived
ON work_orders.order_number = Work_Orders_Archived.order_number
WHERE COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = '919630') AS cntWO,
SUM(Laborhours) AS sumLaborHours,
SUM(LaborCost) AS sumLaborCost,
SUM(MaterialCost*MaterialQuanity) AS sumMaterialCost
FROM work_orders
FULL OUTER JOIN Work_Orders_Archived
ON work_orders.order_number = Work_Orders_Archived.order_number
LEFT OUTER JOIN
(SELECT HoursWorked AS Laborhours, TotalDollars AS LaborCost, WorkOrderNo
FROM LaborDetail) AS LD
ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = LD.WorkOrderNo
LEFT OUTER JOIN
(SELECT UnitCost AS MaterialCost, Qty AS MaterialQuanity, OrderNumber
FROM WorkOrderInventory) AS WOI
ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = WOI.OrderNumber
WHERE COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = '919630'
GROUP BY CASE WHEN COALESCE(work_orders.location, Work_Orders_Archived.location) IS NULL
THEN '' ELSE COALESCE(work_orders.location, Work_Orders_Archived.location) END
ORDER BY sFunction
Try using the SUM function inside a derived table subquery when doing the full join to "WorkOrderInventory" like so...
select
...
sum(hrs) as sumlaborhrs,
sum(cost) as sumlaborcost,
-- calculate material cost in subquery
summaterialcost
from labordetail a
full outer join
(select ordernumber, sum(materialcost) as summaterialcost
from WorkOrderInventory
group by ordernumber
) b on a.workorderno = b.ordernumber
i created a simple sql fiddle to demonstrate this (i simplified your query for examples sake)
Looks to me that work_orders and work_orders_archived contains the same thing and you need both tables as if they were one table. So you could instead of joining create a UNION and use it as if it was one table:
select location as sfunction
from
(select location
from work_orders
union location
from work_orders_archived)
Then you use it to join the rest. What DBMS are you on? You could use WITH. But this does not exist on MYSQL.
with wo as
(select location as sfunction, order_number
from work_orders
union location, order_number
from work_orders_archived)
select sfunction,
count(*)
SUM(Laborhours) AS sumLaborHours,
SUM(LaborCost) AS sumLaborCost,
SUM(MaterialCost*MaterialQuanity) AS sumMaterialCost
from wo
LEFT OUTER JOIN
(SELECT HoursWorked AS Laborhours, TotalDollars AS LaborCost, WorkOrderNo
FROM LaborDetail) AS LD
ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = LD.WorkOrderNo
LEFT OUTER JOIN
(SELECT UnitCost AS MaterialCost, Qty AS MaterialQuanity, OrderNumber
FROM WorkOrderInventory) AS WOI
ON COALESCE(work_orders.order_number, Work_Orders_Archived.order_number) = WOI.OrderNumber
where wo.order_number = '919630'
group by sfunction
order by sfunction
The best guess is that the work orders appear more than once in one of the tables. Try these queries to check for duplicates in the two most obvious candidate tables:
select cnt, COUNT(*), MIN(order_number), MAX(order_number)
from (select order_number, COUNT(*) as cnt
from work_orders
group by order_number
) t
group by cnt
order by 1;
select cnt, COUNT(*), MIN(order_number), MAX(order_number)
from (select order_number, COUNT(*) as cnt
from work_orders_archived
group by order_number
) t
group by cnt
order by 1;
If either returns a row where cnt is not 1, then you have duplicates in the tables.

Counting items on tables

I need your help. I have this code to query my machines which are on rental, on stock, and on my outlets, but this only works if I input an itemID, which means it will only query one item at a time. I need to query the number of machines on rental and on outlets, parallel to the number of stock on hand.
alter procedure GetItemsForQueries
#itemID varchar(15)
as begin
select i.ItemName, m.MachineModel, i.SellingPrice, i.QuantityOnHand,
(select COUNT(*) from ClientMachine where AcquisitionType = 'Rental' and ItemID = #itemID) as 'Quantity on Rentals',
(select COUNT(*) from OutletMachine where ItemID = #itemID) as 'Quantity on Outlets'
from Item i inner join Machine m on (m.ItemID = i.ItemID)
where i.ItemID = #itemID
end
Two subqueries should do it - something like this...
In a nutshell, find all the machines, join against a subquery which finds the count id thats rental and join again against another subquery that finds the count per outlet machine...
select m.itemid,
ifnull(ccount,0) as rental_count,
ifnull(ocount,0) as outlet_count
from Machine m
left join (select itemid,
count(*) as ccount
from ClientMachine
where AcquisitionType = 'Rental' group by ItemID) a1 on (a1.itemid=m.itemid)
left join (select itemid,
count(*) as ocount
from OutletMachine group by ItemID) a2 on (a2.itemid=m.itemid)
Of the top of my head (could have some syntax errors but the logic is there)
select i.ItemId, i.ItemName, m.MachineModel, i.SellingPrice, i.QuantityOnHand, rental.rentalCount, outlet.outletCount
from Item i
left join (select ItemId, count(*) as 'rentalCount' from ClientMachine Where AcquisitionType = 'Rental' group by ItemId) rental on rental.ItemId = i.ItemId
left join (select ItemId, count(*) as 'outletCount' from OutletMachine group by ItemId) outlet on outlet.ItemId = i.ItemId
inner join Machine m on (m.ItemID = i.ItemID)
Check this code :
select i.ItemName,
m.MachineModel,
i.SellingPrice,
i.QuantityOnHand,
(select COUNT(*) from ClientMachine where AcquisitionType = 'Rental' and ItemID = i.ItemID) as 'Quantity on Rentals',
(select COUNT(*) from OutletMachine where ItemID = i.ItemID) as 'Quantity on Outlets'
from Item i inner join Machine m on (m.ItemID = i.ItemID)

Inner join with WHERE clause affecting second join

I have this query and the top inner join works fine but when i add the second join i receive incorrect syntax near 'INNER' anyone any idea why?
SELECT Time_ID,
Site_Type_ID,
SUM (staging.dbo.incoming_measure.ring_time) AS Ring_Time,
SUM (staging.dbo.incoming_measure.hold_time) As Hold_Time,
SUM (staging.dbo.incoming_measure.talk_time) AS Talk_Time,
SUM (staging.dbo.incoming_measure.acw_time) AS ACW_Time
FROM staging.dbo.incoming_measure
INNER JOIN
(SELECT Time_ID FROM datamartend.dbo.Time_Dim ) TimeID
ON TimeID.Time_ID = incoming_measure.StartTime
INNER JOIN
(SELECT Site_Type_ID, Site_Type_Code FROM datamartend.dbo.Site_Type_dim) SiteID
ON SiteID.Site_Type_ID = incoming_measure.DBID
WHERE StartTimeDate BETWEEN StartTimeDate AND EndTimeDate
AND
WHERE SiteId.Site_type_code = incoming_measure.DBID
GROUP BY time_id, site_type_id
You have to move your WHERE down above the GROUP BY:
WHERE StartTimeDate BETWEEN StartTimeDate AND EndTimeDate
AND SiteId.Site_type_code = incoming_measure.DBID
Group by time_id, site_type_id