SQL Server行成列,限制行,

时间:2016-12-12 15:57:08

标签: sql sql-server pivot

我一直在搞乱枢轴功能,但我不确定它是否符合我的要求。我有一个父子关系,其中存储票可以有多个因素和值。我很乐意将结果数量限制为预定义的数字,对于这个问题我会选择两个。

这是一个更简单的结果集。

StorageTicketID FactorID    FactorValue
---------------------------------------
23               116        90
23               210        13.2

我认为透视无效,因为FactorId存在大量可能性,我对创建以每个特定FactorId命名的列不感兴趣。

这是我想出的。它有效,但我希望有更好的方法!

select 
    StorageTicketID,
    ROW_NUMBER() over (order by StorageTicketID) rownumber, 
    glfr.FactorID, glfr.FactorValue 
into 
    #temp1 
from 
    pgf_master.dbo.StorageTicket st  
join 
    PGF_Master.dbo.GrainLoadFactorResult glfr on glfr.ParentID = st.StorageTicketID
                                              and StorageTicketID = 23
                                              and glfr.ParentTypeId = 2

select 
    max(StorageTicketID) ID,
    (select factorid from #temp1 
     where rownumber = 1) F1, 
    (select factorvalue from #temp1 
     where rownumber = 1) V1,
    (select factorid from #temp1 
     where rownumber = 2) F2, 
    (select factorvalue from #temp1 
     where rownumber = 2) V2
from 
    #temp1
group by 
    StorageTicketI

这是输出:

ID  F1  V1  F2  V2
--------------------
23  116 90  210 13.2

3 个答案:

答案 0 :(得分:1)

我与Row_Number()协同工作的简单条件聚合可以做到这一点

Select StorageTicketID
      ,F1 = max(case when RN=1 then FactorID    else null end)
      ,V1 = max(case when RN=1 then FactorValue else null end)
      ,F2 = max(case when RN=2 then FactorID    else null end)
      ,V2 = max(case when RN=2 then FactorValue else null end)
 From  (
        Select *,RN=Row_Number() over (Partition By StorageTicketID Order By (Select NULL))
         From  YourTable
       ) A
 Group By StorageTicketID

返回

StorageTicketID F1    V1      F2    V2
23              116   90.00   210   13.20
  

编辑 - 为了好玩,我添加了动态版

Declare @SQL varchar(max) = (Select ',F'+RN+' = max(case when RN='+RN+' then FactorID else null end),V'+RN+' = max(case when RN='+RN+' then FactorValue else null end)' From (Select Distinct RN=cast(Row_Number() over (Partition By StorageTicketID Order By (Select null)) as varchar(15)) from YourTable) A Order by 1 For XML Path(''))
Select  @SQL = '
Select StorageTicketID'+@SQL+'
 From  (
        Select *,RN=Row_Number() over (Partition By StorageTicketID Order By (Select NULL))
         From  YourTable
       ) A
 Group By StorageTicketID
'
Exec(@SQL);

答案 1 :(得分:0)

您可以按照您希望的方式对派生表执行PIVOT。

答案 2 :(得分:0)

根据约翰的意见,我选择

Select StorageTicketID
      ,F1 = max(case when RN=1 then FactorID    else null end)
      ,V1 = max(case when RN=1 then FactorValue else null end)
      ,F2 = max(case when RN=2 then FactorID    else null end)
      ,V2 = max(case when RN=2 then FactorValue else null end)
 From  (
        Select st.StorageTicketID,glfr.FactorID, glfr.FactorValue,RN=Row_Number() over (Partition By StorageTicketID Order By (Select NULL))
         From  storageticket st
         join GrainLoadFactorResult glfr on st.StorageTicketID = glfr.ParentID
       ) A
 Group By StorageTicketID

我只是张贴这个,因为我认为显示加入可能会有所帮助。