Item rows duplicate and SUM for Total Expense - sql

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

Related

Invalid subquery, trying to get the customer ID that goes along with the invoice

Here is my SQL, I am trying to get the DISTINCT item ids that have not been invoiced in the past two years that also have a qty on hand greater than 0. I am having an issue getting the last customer id that was invoiced for each distinct item id.
SELECT DISTINCT
im.item_id,
MAX(il.date_created),
(SELECT TOP 1 customer_id
FROM invoice_hdr ih2
WHERE ih.invoice_no = ih2.invoice_no) AS customer_id,
inv_loc.qty_on_hand,
ih.sales_location_id,
MAX(il.commission_cost)
FROM
invoice_hdr ih
INNER JOIN
invoice_line il ON ih.invoice_no = il.invoice_no
INNER JOIN
inv_mast im ON il.inv_mast_uid = im.inv_mast_uid
INNER JOIN
inv_loc ON im.inv_mast_uid = inv_loc.inv_mast_uid
WHERE
inv_loc.qty_on_hand > '0'
GROUP BY
im.item_id, inv_loc.qty_on_hand, ih.sales_location_id
HAVING
(MAX(il.date_created) < DATEADD(year, -2, GETDATE()))
I get this error:
Column 'invoice_hdr.invoice_no' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I understand the error, but no matter what I try I cannot get it to work.
I was able to get the correct data with the following query:
SELECT DISTINCT il.item_id,
ih.customer_id,
il.customer_part_number,
il.date_created,
SUM(inv_loc.qty_on_hand) AS [Qty On Hand],
ih.sales_location_id,
MAX(il.commission_cost) AS [Max Commission Cost]
FROM invoice_hdr ih
JOIN invoice_line il ON ih.invoice_no = il.invoice_no
JOIN inv_loc ON il.inv_mast_uid = inv_loc.inv_mast_uid
WHERE (SELECT TOP 1 il2.date_created FROM invoice_line il2 WHERE il2.item_id = il.item_id ORDER BY il2.date_created DESC) < DATEADD(YEAR, -2, GETDATE())
AND (SELECT TOP 1 il2.invoice_no FROM invoice_line il2 WHERE il2.item_id = il.item_id ORDER BY il2.date_created DESC) = ih.invoice_no
GROUP BY il.item_id,
ih.customer_id,
il.date_created,
ih.sales_location_id,
customer_part_number
HAVING SUM(inv_loc.qty_on_hand) > 0
ORDER BY il.item_id

Anyway to improve this SQL to avoid multiple Joins

I want to get sales result for 10 days for each product which is in my orders_summary table. Currently I'm joining orders_summary table 10 times to get sales for each day. Is there any better way to get this data?
Current sql:
SELECT P.ID,
P.SKU,
FIRST_DAY.ITEMS AS ITEMS_1,
FIRST_DAY.ORDERS AS ORDERS_1,
SECOND_DAY.ITEMS AS ITEMS_2,
SECOND_DAY.ORDERS AS ORDERS_2
FROM PRODUCTS AS P
LEFT JOIN
(SELECT SKU,
AMOUNT AS ITEMS,
ARRAY_LENGTH(LIST,
1) AS ORDERS
FROM ORDERS_SUMMARY
WHERE ORDER_DATE = TO_TIMESTAMP(1633158000000 / 1000.0)) AS FIRST_DAY ON P.SKU = FIRST_DAY.SKU
LEFT JOIN
(SELECT SKU,
AMOUNT AS ITEMS,
ARRAY_LENGTH(LIST,
1) AS ORDERS
FROM ORDERS_SUMMARY
WHERE ORDER_DATE = TO_TIMESTAMP(1633676400000 / 1000.0)) AS SECOND_DAY ON P.SKU = SECOND_DAY.SKU
...
result:
select main.sku, jsonb_populate_record(null::examples.table_fields, main.json_data)
from
(
select t2.sku, jsonb_object_agg(t2.itemNames, t2.items) || jsonb_object_agg(t2.orderNames, t2.orders) as json_data from
(
select
pr.sku,
'items' || tbl_dates.num::varchar as itemNames,
coalesce(sum(sOrd.amount), 0) as items,
'orders' || tbl_dates.num::varchar as orderNames,
coalesce(sum(sOrd.qty), 0) as orders
-- tbl_dates.dates
from products pr
inner join (
select tt.num, ('2021-01-01'::date + tt.num - 1) as dates
from (
select t.num from generate_series(1, 10, 1) AS t(num)
) tt
) tbl_dates on true
left join orders_summary sOrd on sOrd.sku = pr.sku and sOrd.order_date::date = tbl_dates.dates
group by pr.sku, tbl_dates.num, tbl_dates.dates
order by tbl_dates.num
) t2
group by t2.sku
) main;
I wrote simple select query, if you want to use a function then you can change this is '2021-01-01'::date to input variable and in this code generate_series(1, 10, 1) you can change 10 to the input variable

Pull top percent of IDs from a list based off of another CTE percentage

I have the below CTE to pull in membership then to pull in all claims for those members ( if they had a claim hit within the date parameters) , now from the total membership (=1961) I need to pull in the TOP 3% or 0.03 from the claims CTE. I see 1961*0.03 is rounded to 59, so I need to pull in the top (59) Medicaid IDs from Claims with the highest total of claims utilization .
So for example in the number_to_pull CTE that gives what lines need to pull in ( it gives the 3% of membership ), then in the sum_of_claims CTE I want to ONLY pull in the top 3% Medicaid IDs from Claims CTE.. Since the membership can change depending on the date parms I want the sum_of_claims to have something like the below but I am not sure how to get started
End result is I will have a list top (3%) of Medicaid IDs who have the most hits per claim for the date span called out
I need something like this, but I want it to pull in whatever the number is in the number_to_pull CTE and then to pull That number based off of the sum of claims.
Select Top ( select
round(count(mt.medicaid_no)*0.03) as percentt
from membership mt)
cll.medicaid_no
,count(distinct claim_number) as sum_of_claims
from claims cll
Group by cll.medicaid_no
) select * from sum_of_claims
This is what my codes actually looks like
WITH
DATES AS
(
select TRUNC(TRUNC(SYSDATE,'y')-1,'y') as startdate,
TRUNC(SYSDATE,'y')-1 as enddate
from dual
),
membership as (
select Distinct
mbr.medicaid_no
,mbd.memb_dim_id
,mbd.memb_demographics_full_date
from dw.fact_member_demographics mbd
inner join dates d
on 1=1
inner join dw.DIM_MEMBER mbr
on mbd.memb_dim_id = mbr.memb_dim_id
Where EXTRACT(YEAR FROM mbd.memb_demographics_full_date)= extract(year from d.startdate)
and mbd.company_dim_id in ('575')
and mbd.age > 18
) ---select * from membership
,number_to_pull as (
select
round(count(mt.medicaid_no)*0.03) as percentt
from membership mt
) ---select * from top_number
,Claims as (
select
mbdd.medicaid_no
,mbdd.memb_dim_id
,dc.company_desc
,cl.primary_svc_date
,cl.claim_number
,case when cl.io_flag_dim_id = '1' then 'Inpatient'
when cl.io_flag_dim_id = '2' then 'Outpatient' else 'false' end as In_Op
,cl.admit_type
,proc.procedure_code
,dx1.diagnosis_code as dx1
,dx1.diagnosis_short_desc as dx1desc
,dx2.diagnosis_code as dx2
,dx2.diagnosis_short_desc as dx2desc
,dx3.diagnosis_code as dx3
,dx3.diagnosis_short_desc as dx3desc
,dx4.diagnosis_code as dx4
,dx4.diagnosis_short_desc as dx4desc
,dx5.diagnosis_code as dx5
,dx5.diagnosis_short_desc as dx5desc
,bt.inp_outp_ind
from membership mbdd
left join dw.fact_claim cl
on mbdd.memb_dim_id = cl.memb_dim_id
inner join dates d
on 1=1
inner join dw.DIM_PROCEDURE_CODE proc
on cl.cpt_code_dim_id = proc.procedure_dim_id
inner join dw.DIM_DIAGNOSIS dx1
on cl.diagnosis_1_dim_id = dx1.diagnosis_dim_id
inner join dw.DIM_DIAGNOSIS dx2
on cl.diagnosis_2_dim_id = dx2.diagnosis_dim_id
inner join dw.DIM_DIAGNOSIS dx3
on cl.diagnosis_3_dim_id = dx3.diagnosis_dim_id
inner join dw.DIM_DIAGNOSIS dx4
on cl.diagnosis_4_dim_id = dx4.diagnosis_dim_id
inner join dw.DIM_DIAGNOSIS dx5
on cl.diagnosis_5_dim_id = dx5.diagnosis_dim_id
inner join dw.DIM_BILL_TYPE bt
on cl.bill_type_dim_id = bt.bill_type_dim_id
inner join dw.DIM_COMPANY dc
on cl.company_dim_id = dc.company_dim_id
Where cl.primary_svc_date between d.startdate and d.enddate
and cl.company_dim_id in ('575')
and CL.WHOLE_CLAIM_STATUS_DIM_ID IN (1,2)
and cl.io_flag_dim_id in ('1','2')
) ---select * from claims
,sum_of_claims AS (
Select
---- this is where I want to pull in the top 3% based off of membeship and sum of claims per Medicaid
cll.medicaid_no
,count(distinct claim_number) as sum_of_claims
from claims cll
Group by cll.medicaid_no
) select * from sum_of_claims
The end result I want is a list of Medicaid IDs and there total sum of claims, but this list will ONLY be the top 59 lines (3%)
MEDICAID_NO SUM_OF_CLAIMS
111111 $12,439.61
333333 $5,315.57
444444 $2,007.00
555555 $1,823.98
888888 $1,770.00
777777 $1,211.47
9999999 $1,157.61
6666666 $1,068.76
If I read your question, correctly, you want to get the top 3% here? This is the final query:
select * from sum_of_claims;
I think you want to replace this with something like the following:
SELECT medicaid_no, sum_of_claims FROM (
SELECT medicaid_no, sum_of_claims, COUNT(*) OVER () AS total_cnt
, ROW_NUMBER() OVER ( ORDER BY sum_of_claims DESC ) AS rn
FROM sum_of_claims
) WHERE rn <= 0.03 * total_cnt;
This will get the "top" 3% of records (where "top" is defined as those with the greatest claim amounts).
By the way, I find it hard to believe that this is what you want:
,count(distinct claim_number) as sum_of_claims
That wouldn't give a sum at all!
Hope this helps.
Thanks David F. I was able to pull in the top 3% members from claims . Below is my code .
WITH
DATES AS
(
select TRUNC(TRUNC(SYSDATE,'y')-1,'y') as startdate,
TRUNC(SYSDATE,'y')-1 as enddate
from dual
),
membership as (
select Distinct
mbr.medicaid_no
,mbd.memb_dim_id
,mbd.memb_demographics_full_date
from dw.fact_member_demographics mbd
inner join dates d
on 1=1
inner join dw.DIM_MEMBER mbr
on mbd.memb_dim_id = mbr.memb_dim_id
Where EXTRACT(YEAR FROM mbd.memb_demographics_full_date)= extract(year from d.startdate)
and mbd.company_dim_id in ('575')
and mbd.age > 18
) ---select * from membership
,Claims as (
select
mbdd.medicaid_no
,mbdd.memb_dim_id
,dc.company_desc
,cl.primary_svc_date
,cl.claim_number
,case when cl.io_flag_dim_id = '1' then 'Inpatient'
when cl.io_flag_dim_id = '2' then 'Outpatient' else 'false' end as In_Op
,cl.admit_type
,proc.procedure_code
,dx1.diagnosis_code as dx1
,dx1.diagnosis_short_desc as dx1desc
,dx2.diagnosis_code as dx2
,dx2.diagnosis_short_desc as dx2desc
,dx3.diagnosis_code as dx3
,dx3.diagnosis_short_desc as dx3desc
,dx4.diagnosis_code as dx4
,dx4.diagnosis_short_desc as dx4desc
,dx5.diagnosis_code as dx5
,dx5.diagnosis_short_desc as dx5desc
,bt.inp_outp_ind
,cl.net_amt
from membership mbdd
left join dw.fact_claim cl
on mbdd.memb_dim_id = cl.memb_dim_id
inner join dates d
on 1=1
inner join dw.DIM_PROCEDURE_CODE proc
on cl.cpt_code_dim_id = proc.procedure_dim_id
inner join dw.DIM_DIAGNOSIS dx1
on cl.diagnosis_1_dim_id = dx1.diagnosis_dim_id
inner join dw.DIM_DIAGNOSIS dx2
on cl.diagnosis_2_dim_id = dx2.diagnosis_dim_id
inner join dw.DIM_DIAGNOSIS dx3
on cl.diagnosis_3_dim_id = dx3.diagnosis_dim_id
inner join dw.DIM_DIAGNOSIS dx4
on cl.diagnosis_4_dim_id = dx4.diagnosis_dim_id
inner join dw.DIM_DIAGNOSIS dx5
on cl.diagnosis_5_dim_id = dx5.diagnosis_dim_id
inner join dw.DIM_BILL_TYPE bt
on cl.bill_type_dim_id = bt.bill_type_dim_id
inner join dw.DIM_COMPANY dc
on cl.company_dim_id = dc.company_dim_id
Where cl.primary_svc_date between d.startdate and d.enddate
and cl.company_dim_id in ('575')
and CL.WHOLE_CLAIM_STATUS_DIM_ID IN (1,2) -- pulling in only paid claims -- use whole claim
and cl.io_flag_dim_id in ('1','2')
) ---select * from claims
,sum_of_claims AS (
Select
cll.medicaid_no
,sum(distinct cll.net_amt) as sum_of_claims
from claims cll
Group by cll.medicaid_no
)
----- this is the new part added below
SELECT medicaid_no, sum_of_claims FROM (
SELECT sh.medicaid_no, sh.sum_of_claims, COUNT(*) OVER () AS total_cnt
, ROW_NUMBER() OVER ( ORDER BY sh.sum_of_claims DESC ) AS rn
FROM sum_of_claims sh
)
Where (rn)<(SELECT round(count(medicaid_no)*0.03) as percentt
from membership)

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;

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.