SQL Server 2014 - 以水平格式显示垂直数据

时间:2017-07-22 23:05:49

标签: sql pivot aggregate-functions sql-server-2014

这是我第一次在stackoverflow上发帖。我希望我能正确地做到这一点。

我有一个SQL Server 2014表,其中包含我需要旋转到具有多列的单个记录中的“Verticle”数据。 bluefeet的回答(SQL Server 2008 Vertical data to Horizontal)几乎让我感到满意,但并不完全。我有临时表“#Columns”,其中包含可根据数据更改的列名列表,以及包含我的数据的表“Transaction”。以下是#Columns表的内容:

ColumnName SeqNum
时间1
区域2 密度3
Ref Index 4
H2SO4 5
pH 6
尿素7
AN 8
TN 9
比率10
NH3 11
SpGr 12
Cl2 13
Fe 14
总数15
评论99

以下是Transaction表中的相关数据:

TransactionId   SamplePoint_Id  SP_Chem_Id  EntryDate   Time    Chem_Id Value   Comment
636 18  108 7/19/2017   1219    21  1   NULL<br>
637 18  109 7/19/2017   1219    22  2   NULL<br>
638 18  110 7/19/2017   1219    28  3   NULL<br>
639 18  111 7/19/2017   1219    1   4   NULL<br>
640 18  112 7/19/2017   1219    51  693.51  NULL<br>
641 18  113 7/19/2017   1219    2   -442.68 NULL<br>
642 18  114 7/19/2017   1219    61  168.58  NULL<br>
643 18  115 7/19/2017   1219    52  -0.64   NULL<br>
644 18  116 7/19/2017   1219    4   0.1 NULL<br>
645 18  117 7/19/2017   1219    62  1.009   NULL<br>
646 18  NULL    7/19/2017   1219    54  5   NULL<br>
647 18  NULL    7/19/2017   1219    12  6   NULL<br>
648 18  NULL    7/19/2017   1219    33  7   NULL<br>
649 18  NULL    7/19/2017   1219    70  NULL    8.88889E+12<br>
650 18  NULL    7/19/2017   1219    71  NULL    NULL<br>
651 18  108 7/19/2017   1220    21  2   NULL<br>
652 18  109 7/19/2017   1220    22  3   NULL<br>
653 18  110 7/19/2017   1220    28  4   NULL<br>
654 18  111 7/19/2017   1220    1   5   NULL<br>
655 18  112 7/19/2017   1220    51  1413.51 NULL<br>
656 18  113 7/19/2017   1220    2   -729.68 NULL<br>
657 18  114 7/19/2017   1220    61  404.01  NULL<br>
658 18  115 7/19/2017   1220    52  -0.52   NULL<br>
659 18  116 7/19/2017   1220    4   0.07    NULL<br>
660 18  117 7/19/2017   1220    62  2.018   NULL<br>
661 18  NULL    7/19/2017   1220    12  7   NULL<br>
662 18  NULL    7/19/2017   1220    54  8   NULL<br>
663 18  NULL    7/19/2017   1220    33  9   NULL<br>
664 18  NULL    7/19/2017   1220    70  NULL    12341234<br>
665 18  NULL    7/19/2017   1220    71  NULL    NULL<br>

这是我的问题:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME(ColumnName)
                    from #Columns
                    group by ColumnName, SeqNum
                    order by SeqNum
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

    set @query = N'SELECT ' + @cols + ' 
            from 
            (
                SELECT 
                c1.ColumnName,
                case when len(t.Comment) > 0 then t.Comment when c1.ColumnName = ''Time'' then t.Time else t.Value end as Value
                FROM [Transaction] t
                join Chemical c on t.Chem_Id = c.ChemicalId    
                join SamplePoint sp on t.SamplePoint_Id = sp.SampleId
                join Source s on sp.Source_Id = s.SourceId         
                join #Columns c1 
                ON c.Abbrev = c1.ColumnName 
                where s.Name = ''' + @SourceName + ''' and t.EntryDate = ''' + @Date + '''
            ) x
            pivot 
            (
                max(Value)
                for ColumnName in (' + @cols + ')
            ) p '

--print @cols
--print @query
execute sp_executesql @query;

这是我的结果:

Time    Area    Density Ref Index   H2SO4   pH  Urea    AN  TN  Ratio   NH3 SpGr    Cl2 Fe  Gross   Comment<br>
1220    NULL    2   3   4   5   693.51  -729.68 404.01  -0.64   0.1 2.018   8   7   9   8888888888888

问题是我只从我的查询中得到一条记录,当我想要的是两条记录 - 一条用于时间= 1219,一条用于时间= 1220.我知道(或认为)问题是聚合函数MAX,它使查询返回具有“最大值”的记录。如何获得两个记录?如果没有聚合函数,我无法使用pivot函数。感谢。

1 个答案:

答案 0 :(得分:1)

您仍然没有从PIVOTed列中排除时间。请注意,当我说从PIVOT中排除时,我并不仅仅意味着您将其从PIVOT ... IN列表中删除,而是您还将内部查询更改为返回时间列为单独柱。这就是为什么我建议仔细阅读add noquote function in front of paste文档以了解PIVOT函数的工作原理。

内部查询SELECT应更改为此(Time作为单独的列返回,而CASE未提及它):

SELECT t.TIME, c1.ColumnName,
    CASE 
        WHEN len(t.Comment) > 0     THEN t.Comment
        ELSE t.Value
    END AS Value

Pivot部分应该成为此(无Time列):

pivot ( max(Value) for ColumnName in ([Area], [Density], [Ref Index], [H2SO4], [pH], [Urea], [AN]], [TN], [Ratio], [NH3], [SpGr], [Cl2], [Fe], [Gross], [Comment]) ) p 

#Columns表中删除时间。