使用SQL服务器PIVOTing数据

时间:2013-09-06 12:27:26

标签: sql sql-server pivot

好吧,当我甚至不知道如何开枪时,我已经击中了牛眼。我根据Technet基础文章(http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx

编写了这个SQL
Select LogTime, Location, LA95Day, LA95Evening, LA95DEn, LA95Night from 
(Select LogTime, Location, LAValue, ValueType  from Project_5_CalculatedData 
     where ValueType in ('LA95Day','LA95Evening','LA95DEn','LA95Night')  )  as c
PIVOT(
Max(LAValue) For ValueType in (LA95Day,LA95Evening,LA95DEn,LA95Night)) as PVt

我的表结构类似于

DataID  Location    LogTime LAValue ValueType
10117   Meter1  2012-09-25 00:00:00.000 71.12   LA95Day
10118   Meter1  2012-09-25 00:00:00.000 55.52   LA95Evening
10119   Meter1  2012-09-25 00:00:00.000 52.69   LA95Night
10120   Meter1  2012-09-25 00:00:00.000 68.62   LA95Den
10121   Meter1  2012-09-26 00:00:00.000 72.21   LA95Day
10122   Meter1  2012-09-26 00:00:00.000 54.10   LA95Evening
10123   Meter1  2012-09-26 00:00:00.000 48.30   LA95Night
10124   Meter1  2012-09-26 00:00:00.000 69.38   LA95Den

修改: 这里的数据不完整..我们有4000行..因此您可以假设MEter2,Meter3,Meter4位置将与样本数据中的天数相同或不同。 **编辑结束**

我们有最多4米来记录值,DataID并不重要。但是我希望所有Meter数据都是对齐的,我写的上述查询部分工作,即它将数据显示为:

LogTime Location    LA95Day LA95Evening LA95DEn LA95Night
2012-09-25 00:00:00.000 Meter1  71.12   55.52   68.62   52.69
2012-09-26 00:00:00.000 Meter1  72.21   54.10   69.38   48.30
2012-09-27 00:00:00.000 Meter1  68.88   47.77   66.05   46.02
2012-09-28 00:00:00.000 Meter1  73.52   49.23   70.56   43.60
2012-09-29 00:00:00.000 Meter1  54.09   44.87   52.85   41.64
2012-09-30 00:00:00.000 Meter1  51.46   48.61   51.94   41.60
2012-10-01 00:00:00.000 Meter1  73.09   51.78   70.17   46.20

但我希望这基于使用的仪表; LAday,晚上,Den和Night将重复多达4次;每米一次用于申请。即欲望输出[列]需要

LogTime M1-LA95Day  M1-LA95Evening  M1-LA95DEn  M1-LA95Night M2-LA95Day M2-LA95Evening  M2-LA95DEn  M2-LA95Night M3-LA95Day M3-LA95Evening  M3-LA95DEn  M3-LA95Night M4-LA95Day M4-LA95Evening  M4-LA95DEn  M4-LA95Night

哦,我正在尝试通过点击和试用,因为我从来没有使用过Pivot,甚至不知道我的上述查询是如何工作的,如果你能解释一下这个查询将帮助我做下一步。感谢。

1 个答案:

答案 0 :(得分:1)

在我看来,您正在尝试将所有电表及其valueTypes列为列。如果是这种情况,那么您应该能够使用以下内容:

Select LogTime, 
    Meter1_LA95Day, Meter1_LA95Evening, Meter1_LA95DEn, Meter1_LA95Night,
    Meter2_LA95Day, Meter2_LA95Evening, Meter2_LA95DEn, Meter2_LA95Night,
    Meter3_LA95Day, Meter3_LA95Evening, Meter3_LA95DEn, Meter3_LA95Night,
    Meter4_LA95Day, Meter4_LA95Evening, Meter4_LA95DEn, Meter4_LA95Night 
from 
(
    Select LogTime, 
        ValueType = Location+'_'+ValueType,
        LAValue       
    from Project_5_CalculatedData 
    where ValueType in ('LA95Day','LA95Evening','LA95DEn','LA95Night')  
)  as c
PIVOT
(
    Max(LAValue) 
    For ValueType in (Meter1_LA95Day, Meter1_LA95Evening, Meter1_LA95DEn, Meter1_LA95Night,
                      Meter2_LA95Day, Meter2_LA95Evening, Meter2_LA95DEn, Meter2_LA95Night,
                      Meter3_LA95Day, Meter3_LA95Evening, Meter3_LA95DEn, Meter3_LA95Night,
                      Meter4_LA95Day, Meter4_LA95Evening, Meter4_LA95DEn, Meter4_LA95Night)
) as PVt;

注意,这假定电表实际上被命名为meter1meter2等。如果您的电表没有被称为meter1等,并且它们的名称可能不同,那么您可能希望使用动态SQL来获得结果:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Location+'_'+ValueType) 
                    from Project_5_CalculatedData
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT LogTime,' + @cols + ' 
            from 
            (
                Select LogTime, 
                    ValueType = Location+''_''+ValueType,
                    LAValue       
                from Project_5_CalculatedData 
                where ValueType in (''LA95Day'',''LA95Evening'',''LA95DEn'',''LA95Night'')  
            ) x
            pivot 
            (
                max(LAValue)
                for ValueType in (' + @cols + ')
            ) p '

execute sp_executesql @query;

这些会产生结果:

+-------------------------+----------------+----------------+--------------------+------------------+----------------+----------------+--------------------+------------------+----------------+----------------+--------------------+------------------+
|         LogTime         | Meter1_LA95Day | Meter1_LA95Den | Meter1_LA95Evening | Meter1_LA95Night | Meter2_LA95Day | Meter2_LA95Den | Meter2_LA95Evening | Meter2_LA95Night | Meter3_LA95Day | Meter3_LA95Den | Meter3_LA95Evening | Meter3_LA95Night |
+-------------------------+----------------+----------------+--------------------+------------------+----------------+----------------+--------------------+------------------+----------------+----------------+--------------------+------------------+
| 2012-09-25 00:00:00.000 | 71.12          | 68.62          | 55.52              | 52.69            | 71.12          | 68.62          | 55.52              | 52.69            | NULL           | NULL           | NULL               | NULL             |
| 2012-09-26 00:00:00.000 | 72.21          | 69.38          | 54.10              | 48.30            | NULL           | NULL           | NULL               | NULL             | 72.21          | 69.38          | 54.10              | 48.30            |
+-------------------------+----------------+----------------+--------------------+------------------+----------------+----------------+--------------------+------------------+----------------+----------------+--------------------+------------------+