将列转换为行

时间:2015-10-01 13:49:38

标签: sql sql-server-2012

我有以下查询:

<% title "Locations" %>  

<%= form_tag locations_path, :method => :get do %>  
  <p>  
    <%= text_field_tag :search, params[:search] %>  
    <%= submit_tag "Search Near", :name => nil %>  
<% end %>  

返回如下数据:

enter image description here

说明:

为了制造10MM钢棒,使用坯料作为原料。任何ItemCode&#39; BYP%&#39;是固体浪费的一部分。每个DocNum的净数量是&#39; MM&#39;重量产生的钢。例如,对于DocNum 348,以下内容用作输入:

enter image description here

然而,对于该DocNum,生产了147.359的10 MM钢,这意味着缺失的3.5​​2(150.879 - 147.359)是燃烧损失(非固体)。

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

enter image description here

3 个答案:

答案 0 :(得分: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这样的语言做一些甚至可能更好,因为现在每次获取的信息都被提取两次(并且查询变成了两倍)。

答案 1 :(得分: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

输出继电器:

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 :(得分:0)

使用UNION ALL将您的原始查询与第BurnLossGROUP BY T0.DocuNum查询结合起来SUM(T1.PlannedQty) - T0.PlannedQty和第三个Net查询以显示{{} 1}}