Без использования агрегатной функции мы можем сделать pivot в SQL - PullRequest
0 голосов
/ 04 марта 2019
  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 голосов
/ 05 марта 2019

Нет, невозможно выполнить PIVOT без агрегатной функции, но вы можете сделать агрегатную функцию произвольной, если в группе будет только одна исходная строка.Из вашего вопроса не сразу понятно, какова ваша логика:

Например, у вас есть два значения для времени 12 (KA108112 и KA106360) и 3 строки для времени 13(TN04F6726, TN28C3709, TN52C4788), так что есть несколько разных способов объединить эти два.

Вы можете вернуть декартово произведение:

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

Или вы можете вернуть каждый результат один раз, например,

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

Но вам также необходимо предоставить дополнительную логику, т.е.почему KA106360 совпадает с TN04F6726, а не с любыми другими двумя значениями (в приведенном выше примере у меня есть ordererd Trailer_RegNo в алфавитном порядке каждый раз, но может быть любое количество способов сделать это.

Исходя из вашего комментария, кажется, что вы хотите произвольно соединить значения, поэтому для того, чтобы убедиться, что каждое значение представлено, необходимо сделать каждую строку уникальной, что можно сделать с помощью 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');

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;
...