2015-10-01 5 views
2

У меня есть следующий запрос:Преобразование столбца в строку

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}) 

, который возвращает данные, такие как:

enter image description here

Пояснение:

Для того, чтобы сделать 10 ММ стальные стержни, заготовки используются в качестве сырья. Любой ItemCode «BYP%» является частью твердых потерь. Чистое количество для каждого DocNum - это количество стали «ММ», произведенной по весу. Например, для Docnum 348, следующие используются в качестве входов:

enter image description here

Однако для этого Docnum, 147,359 ММ стали 10 было получено, что означает отсутствие 3,52 (150,879 - 147,359) сжигается потери (не твердое вещество).

Как изменить запрос, что для каждого Docnum, запрос возвращает:

enter image description here

ответ

2

Смотрите код SQL ниже.

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 
2

Вы должны использовать UNION. Я думаю

(/*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 

должен работать, хотя это может быть даже лучше, чтобы сделать некоторые из этого в языке, как PHP, потому что теперь каждый бит информации извлекается дважды (и запрос становится в два раза до тех пор).

0

Используйте UNION ALL совместить оригинальный запрос со вторым BurnLoss запроса GROUP BY T0.DocuNum, который вычисляет SUM(T1.PlannedQty) - T0.PlannedQty и третьего Net запроса, чтобы показать T0.PlannedQty

Смежные вопросы