Sql 将列转换为行

Sql 将列转换为行,sql,sql-server-2012,Sql,Sql Server 2012,我有以下疑问: 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.Item

我有以下疑问:

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})
返回如下数据:

说明:

为了制造10毫米的钢筋,钢坯被用作原材料。任何项目代码“BYP%”都是固体损耗的一部分。每个DocNum的净数量是按重量生产的“MM”钢的数量。例如,对于DocNum 348,以下内容用作输入:

然而,对于DocNum,生产了147.359的10 MM钢,这意味着缺少的3.52(150.879-147.359)是烧损(非固体)

如何修改查询,以便对于每个DocNum,查询返回:


你应该使用一个接头。我想

(/*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这样的语言中执行某些操作可能更好,因为现在每一位信息都会被提取两次(并且查询的长度会增加两倍).

使用
UNION ALL
将原始查询与第二个
BurnLoss
查询相结合,该查询按T0.DocuNum分组,计算
总和(T1.PlannedQty)-T0.PlannedQty
和第三个
Net
查询显示
T0.PlannedQty

请参见下面的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
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