SQL пивот с текстовыми полями - PullRequest
0 голосов
/ 18 марта 2020

Простите, но я не могу заставить это работать. Я могу найти множество сложных сводок, используя числовые значения c, но ничего не основано на c, основанном на строках, на которых можно строить.

Предположим, что это мой исходный запрос из временной таблицы. Я не могу изменить это:

select * from @tmpTable

Это обеспечивает 12 строк:

Row | Name           | Code
---------------------------------
1   | July 2019      | 19/20-01
2   | August 2019    | 19/20-02
3   | September 2019 | 19/20-03 
..  ..                 ..
12  | June 2020      | 19/20-12

Я хочу повернуть это и вернуть данные следующим образом:

    Data Type  |      [0]     |      [1]      |       [3]        |  [12]
---------------------------------------------------------------------------
    Name       |   July 2019  |  August 2019  | September 2019   |  June 2020
    Code       |   19/20-01   |  19/20-02     | 19/20-03         |  19/20-12

Заранее спасибо ..

1 Ответ

1 голос
/ 18 марта 2020

Строки и числа не сильно отличаются друг от друга, просто вы не можете использовать числовые агрегаторы c, такие как SUM или AVG. С MAX все будет в порядке, и в этом случае у вас будет только одно значение, поэтому ничего не будет потеряно

Вам нужно вытащить данные в более высокое представление ключ / значение, прежде чем повернуть их назад, чтобы посмотреть в обратном направлении. как это происходит сейчас

Отключить данные:

WITH upiv AS(
   SELECT 'Name' as t, row as r, name as v FROM @tempTable
   UNION ALL
   SELECT 'Code' as t, row, code FROM @tempTable
)

Теперь данные могут быть сгруппированы и условно агрегированы по столбцам r:

SELECT
  t,
  MAX(CASE WHEN r = 1 THEN v END) as r1,
  MAX(CASE WHEN r = 2 THEN v END) as r2,
  ...
  MAX(CASE WHEN r = 12 THEN v END) as r12
FROM
  upiv
GROUP BY
  t

Вы будете Мне нужно соединить два блока sql, которые я здесь представляю, чтобы они образовали один оператор sql. Если вы хотите узнать больше о том, как это работает, я предлагаю вам выполнить оператор sql внутри блока with, взглянуть на него, а также удалить группу из слов / max из полного оператора и посмотреть на результат. Вы увидите, что запрос блока WITH делает данные выше, по сути, это пара ключ / значение, которая отслеживает тип данных (имя или код). Когда вы запустите полный sql без группировки по / max, вы увидите, что высокие данные растягиваются в стороны, давая много нулей и диагональный набор данных ячейки (если упорядочено по r). Группировка по сворачивает все эти нули, потому что МАКС выберет любое значение сверх нуля (из которых только одно)

Вы также можете сделать это как UNPIVOT, за которым следует PIVOT. Я всегда предпочитал использовать эту форму, потому что не каждая база данных поддерживает ключевые слова UN / PIVOT. Можно утверждать, что UNPIVOT / PIVOT могли бы работать лучше, потому что могут быть сделаны определенные c оптимизации, которые разработчики могут сделать (например, UNPIVOT может сканировать таблицу в одиночку; такой подход с множественным объединением может потребовать многократных сканирований и способов обхода, которые могут потребовать больше памяти), но в в этом случае всего 12 рядов. Я подозреваю, что вы используете SQLServer, но если вы используете базу данных, которая не понимает WITH, вы можете поместить в скобки оператор WITH (включая скобки) между FROM и upiv, чтобы сделать его подзапросом если шаблон SELECT ... FROM (SELECT ... UNION ALL SELECT ...) upiv GROUP BY ...; нет никакой разницы

Я оставлю переименование выходных столбцов как упражнение для вас, но я настоятельно рекомендую вам не ставить пробелы или квадратные скобки в именах столбцов, как показано в вашем вопросе

...