Преобразовать результаты SQL-запросов - PullRequest
1 голос
/ 26 марта 2011

Мне нужно взять некоторые результаты запроса и выровнять их для отчета.

DECLARE @randomTable table (ID int, OtherID int, Val varchar(max))

insert into @randomTable(ID, OtherID, Val)
values (1, 100, 'Some Value 1'), (2, 100, 'Some Other 2'),
       (3, 100, 'Some Value 3'), (4, 200, 'Some Other 4'),
       (5, 200, 'Some Value 5'), (6, 300, 'Some Other 6'),
       (7, 300, 'Some Value 7'), (8, 300, 'Some Other 8'),
       (9, 400, 'Some Value 9'), (10, 500, 'Some Other 10')            

select OtherID, Val from @randomTable

Результаты:

--  100 | Some Value 1
--  100 | Some Other 2
--  100 | Some Value 3
--  200 | Some Other 4
--  200 | Some Value 5
--  300 | Some Other 6
--  300 | Some Value 7
--  300 | Some Other 8
--  400 | Some Value 9
--  500 | Some Other 10

Есть ли способ SQL изменить это, чтобы выбрать как:

--  100 | Some Value 1 | Some Other 2 | Some Value 3
--  200 | Some Other 4 | Some Value 5
--  300 | Some Other 6 | Some Value 7 | Some Other 8
--  400 | Some Value 9
--  500 | Some Other 10

ПРИМЕЧАНИЕ. Выше приведен пример. Мои реальные данные не являются статичными. Кроме того, в моих реальных данных OtherID - это строковое значение, а Val - это изображения, хранящиеся в виде varbinary.

Конечно, мне нужно ограничить количество столбцов, которые я собираюсь разрешить. Я думаю, максимум 5 (после этого я могу потерять лишние строки).

Есть ли способ сделать это?

Ответы [ 3 ]

4 голосов
/ 26 марта 2011
;WITH cte
     AS (SELECT OtherID,
                Val,
                ROW_NUMBER() OVER (PARTITION BY OtherID ORDER BY (SELECT 0)) rn
         FROM   @randomTable)
SELECT OtherID,
       [1],
       [2],
       [3],
       [4],
       [5]
FROM   cte PIVOT( MAX(Val) FOR rn IN ([1], [2], [3], [4], [5])) AS PivotTable;  

Чтобы дать какое-то объяснение, SELECT * FROM cte вернет следующее.

OtherID     Val                  rn
----------- -------------------- ---
100         Some Value 1         1
100         Some Other 2         2
100         Some Value 3         3
200         Some Other 4         1
200         Some Value 5         2
300         Some Other 6         1
300         Some Value 7         2
300         Some Other 8         3
400         Some Value 9         1
500         Some Other 10        1

Я добавил столбец row_number, чтобы дать что-то для использования в PIVOT. Обратите внимание, что в комбинации OtherID,rn имеется ноль или одна строка. Оператор PIVOT эквивалентен следующему.

SELECT OtherID,
       MAX(CASE WHEN rn=1 THEN Val END) AS [1],
       MAX(CASE WHEN rn=2 THEN Val END) AS [2],
       MAX(CASE WHEN rn=3 THEN Val END) AS [3],
       MAX(CASE WHEN rn=4 THEN Val END) AS [4],
       MAX(CASE WHEN rn=5 THEN Val END) AS [5]
FROM cte
GROUP BY OtherID /*You want one row per OtherID */
2 голосов
/ 26 марта 2011

Я не уверен, хотите ли вы развернуть столбцы или объединить результаты в один столбец (для отчетов).

Если вы ищете динамический пивот, просмотрите статью здесь: ссылка и последующие комментарии там. Если вы можете ограничить число столбцов, участвующих в сводке, вы можете использовать оператор сводки (как уже упоминалось) и получить гораздо лучшую производительность.

Если вы хотите объединить строки в столбцы, просмотрите приведенный ниже запрос. Использование XML PATH имеет некоторые последствия со специальными символами (<и т. Д.), Поэтому, если это применимо к вашей ситуации, пожалуйста, отправьте ответ, и мы можем расширить этот простой пример. </p>

 -- if you have normalized type table use it instead of this cte
    ;with   c_distinct (OtherId) 
    as      (   select  distinct OtherId 
                from    @randomTable
            )
    select  OtherId,
            stuff(c, 1, 2, '') 
    from    c_distinct cd
    cross
    apply   (   select  '| ' + Val
                from    @randomTable rt
                where   cd.OtherId = rt.OtherId
                for xml path('')
            ) d(c)
0 голосов
/ 26 марта 2011

То, что вы просите - это денормализация , верно?

Я думаю, что на ваш вопрос здесь ответят: Денормализация данных (возможно, сводная?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...