Reputation: 1936
I have the following query:
SELECT DISTINCT
T0.DocNum, T0.Status, T1.ItemCode, T2.ItemName,
T1.PlannedQty, T0.PlannedQty AS 'Net Quantity'
FROM
OWOR T0
INNER JOIN
WOR1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN
OITM T2 ON T0.ItemCode = T2.ItemCode
WHERE
T0.Status = 'L' AND
T1.ItemCode IN ('BYP/RM/001', 'BYP/RM/002', 'BYP/RM/003', 'BYP/RM/004','BILLET') AND
T2.ItmsGrpCod = 111 AND
(T0.PostDate BETWEEN (SELECT Dateadd(month, Datediff(month, 0, {?EndDate}), 0)) AND {?EndDate})
that returns data like:
Explanation:
To make 10 MM steel bars, billets are used as raw materials. Any ItemCode 'BYP%' is part of solid wastage. The net quantity for every DocNum is the amount of 'MM' steel produced by weight. For example, for DocNum 348, the following are used as inputs:
However for that DocNum, 147.359 of 10 MM steel was produced, meaning the missing 3.52 (150.879 - 147.359) is burned loss (not solid).
How do I modify the query such that for each DocNum, the query returns:
Upvotes: 2
Views: 76
Reputation: 5117
See the SQL code below.
declare @input_tbl table ( doc_num int, item_code varchar(15), item_name varchar(10), planned_qty decimal(15,9), net_qty decimal(15,9) )
declare @ouput_tbl table ( doc_num int, item varchar(15), name varchar(10), quantity decimal(15,9) )
-- Inserting sample data shown by you. You will have to replace this with your 1st query.
insert into @input_tbl values (348, 'BILLET' , '10MM', 154.629000, 147.359000)
insert into @input_tbl values (348, 'BYP/RM/001' , '10MM', -1.008000, 147.359000)
insert into @input_tbl values (348, 'BYP/RM/003' , '10MM', -1.569000, 147.359000)
insert into @input_tbl values (348, 'BYP/RM/004' , '10MM', -1.173000, 147.359000)
-- This stores unique doc numbers from input data
declare @doc_tbl table ( id int identity(1,1), doc_num int )
insert into @doc_tbl select distinct doc_num from @input_tbl
-- Loop through each unique doc number in the input data
declare @doc_ctr int = 1
declare @max_doc_id int = (select max(id) from @doc_tbl)
while @doc_ctr <= @max_doc_id
begin
declare @doc_num int
declare @planned_qty_total decimal(15,9)
declare @net_qty decimal(15,9)
declare @burned_loss decimal(15,9)
declare @item_name varchar(15)
select @doc_num = doc_num from @doc_tbl where id = @doc_ctr
select @planned_qty_total = sum(planned_qty) from @input_tbl where doc_num = @doc_num
select distinct @item_name = item_name, @net_qty = net_qty from @input_tbl where doc_num = @doc_num
select @burned_loss = @planned_qty_total - @net_qty
-- 'Union' is also fine but that won't sort the records as desired
insert into @ouput_tbl select doc_num, item_code, item_name, planned_qty from @input_tbl
insert into @ouput_tbl select @doc_num, 'BurnLoss', @item_name, @burned_loss * -1
insert into @ouput_tbl select @doc_num, 'Net', @item_name, @net_qty
set @doc_ctr = @doc_ctr + 1
end
select * from @ouput_tbl
Ouput:
docnum item name quantity
348 BILLET 10MM 154.629000000
348 BYP/RM/001 10MM -1.008000000
348 BYP/RM/003 10MM -1.569000000
348 BYP/RM/004 10MM -1.173000000
348 BurnLoss 10MM -3.520000000
348 Net 10MM 147.359000000
Upvotes: 2
Reputation: 1165
You should use a UNION. I guess
(/*your original query*/)
UNION
SELECT DISTINCT
T0.DocNum, T0.Status, 'BurnLoss' AS ItemCode, T2.ItemName,
SUM(T1.PlannedQuantity)-T0.PlannedQuantity AS PlannedQuantity, T0.PlannedQuantity AS 'Net Quantity'
FROM
OWOR T0
INNER JOIN
WOR1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN
OITM T2 ON T0.ItemCode = T2.ItemCode
WHERE
T0.Status = 'L' AND
T1.ItemCode IN ('BYP/RM/001', 'BYP/RM/002', 'BYP/RM/003', 'BYP/RM/004','BILLET') AND
T2.ItmsGrpCod = 111 AND
(T0.PostDate BETWEEN (SELECT Dateadd(month, Datediff(month, 0, {?EndDate}), 0)) AND {?EndDate})
GROUP BY T0.DocNum
UNION
SELECT DISTINCT
T0.DocNum, T0.Status, 'Net' AS ItemCode, T2.ItemName,
T0.PlannedQuantity, T0.PlannedQuantity AS 'Net Quantity'
FROM
OWOR T0
INNER JOIN
WOR1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN
OITM T2 ON T0.ItemCode = T2.ItemCode
WHERE
T0.Status = 'L' AND
T1.ItemCode IN ('BYP/RM/001', 'BYP/RM/002', 'BYP/RM/003', 'BYP/RM/004','BILLET') AND
T2.ItmsGrpCod = 111 AND
(T0.PostDate BETWEEN (SELECT Dateadd(month, Datediff(month, 0, {?EndDate}), 0)) AND {?EndDate})
GROUP BY T0.DocNum
should work, although it might even be better to do some of this in a language like PHP, because now every bit of information is fetched twice (and the query becomes two times as long).
Upvotes: 2
Reputation: 3314
Use a UNION ALL
to combine your original query with a second BurnLoss
query of GROUP BY T0.DocuNum
that computes SUM(T1.PlannedQty) - T0.PlannedQty
and a third Net
query to show T0.PlannedQty
Upvotes: 0