不使用聚合函数就可以在sql中进行透视

时间:2019-03-04 12:26:19

标签: sql sql-server sql-server-2012

  SELECT 'CFS to Zero' Location, [0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],              
[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23]  FROM                 
(SELECT  Trailer_RegNo,Time FROM #tt )as Tab1                
PIVOT                
(                
max(Trailer_RegNo) FOR Time IN ([0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],              
[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23])) AS Tab2 

对于上述查询,我​​正在获取仅返回1行的数据。图片附在下方 enter image description here

但是由于下表我需要多行 enter image description here

我需要输出为

Location    0        1       2       3       4       5      6       7       8        9        10         11       12        13          14          15              16     17       18        19         20      21       22       23
CFS to Zero NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL        NULL    KA108112    TN52C4788   TN04AH3243  TN04AB6915  TN03H9079   NULL    NULL    NULL    NULL    NULL    NULL    NULL
 CFS to Zero    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL        NULL    KA108112    TN28C3709   TN04AK3631  TN04J6646   TN04AE7461  NULL    NULL    NULL    NULL    NULL    NULL    NULL
etc

1 个答案:

答案 0 :(得分:0)

否,没有聚合函数就无法执行PIVOT,但是您可以通过确保每个组只有一个源行来使聚合函数成为任意函数。从您的问题中并不能立即清楚您的逻辑是什么:

例如,对于时间12,您有两个值(KA108112KA106360),对于时间13您有3行(TN04F6726TN28C3709TN52C4788),因此可以通过几种不同的方式将这两种方式结合使用。

您可以返回笛卡尔积:

12          13
----------------------
KA108112    TN04F6726
KA106360    TN04F6726
KA108112    TN28C3709
KA106360    TN28C3709
KA108112    TN52C4788
KA106360    TN52C4788

或者您可以一次返回每个结果,例如

12          13
----------------------
KA106360    TN04F6726
KA108112    TN28C3709
NULL        TN52C4788

但是您还需要提供其他逻辑,即为什么KA106360TN04F6726匹配,而不是其他两个值中的任何一个(在上面的示例中,我每次都按字母顺序对Trailer_RegNo进行排序,但是可以有许多种方法可以做到这一点。

根据您的评论,您似乎想对值进行任意配对,因此,为了确保每个值都被表示,您需要使每一行都是唯一的,您可以使用ROW_NUMBER()进行操作,例如,< / p>

DECLARE @T TABLE (Time INT, Trailer_RegNo VARCHAR(20));
INSERT @T (Time, Trailer_RegNo)
VALUES (12, 'KA108112'), (12, 'KA106360'), (13, 'TN04F6726'), (13, 'TN28C3709'), (13, 'TN52C4788');

SELECT  Trailer_RegNo, 
        Time,
        RowNumber = ROW_NUMBER() OVER(PARTITION BY [Time] ORDER BY Trailer_RegNo) 
FROM    @T;

哪个给:

Trailer_RegNo   Time    RowNumber
----------------------------------
KA106360        12      1
KA108112        12      2
TN04F6726       13      1
TN28C3709       13      2
TN52C4788       13      3

现在,您可以对商品进行配对了(即KA106360和TN04F6726,KA108112和TN28C3709等)。要更改项目的分组方式,只需要更改ORDER BY功能中的ROW_NUMBER()子句即可。

因此您的最终查询可能类似于:

DECLARE @T TABLE (Time INT, Trailer_RegNo VARCHAR(20));
INSERT @T (Time, Trailer_RegNo)
VALUES (12, 'KA108112'), (12, 'KA106360'), (13, 'TN04F6726'), (13, 'TN28C3709'), (13, 'TN52C4788'),
        (14, 'KA108112'), (15, 'KA106360'), (15, 'TN04F6726'), (1, 'TN28C3709'), (0, 'TN52C4788');

SELECT  'CFS to Zero' Location, 
        [0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],              
        [13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23]
FROM    (   SELECT Trailer_RegNo, 
                    Time,
                    RowNumber = ROW_NUMBER() OVER(PARTITION BY [Time] ORDER BY Trailer_RegNo) 
            FROM    @T 
        ) AS Tab1                
        PIVOT                
        (   MAX(Trailer_RegNo) 
            FOR [Time] IN 
            (   [0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],              
                [13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23]
            )
        ) AS Tab2;