Использование PIVOT с сервером SQL без функции агрегирования - PullRequest
1 голос
/ 10 марта 2020

Я застрял на использовании PIVOT в простом примере (который я полностью приведу ниже). Полное раскрытие, я получил это от https://www.hackerrank.com/. Я выбрал его именно потому, что хочу поближе познакомиться с PIVOT, и это выглядело как простой пример! Я просмотрел многочисленные посты на эту тему и использовал это для того, чтобы вымолвить: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/b76a4668-d0c3-4c51-8d86-117d5c181e69/pivot-without-aggregate-function?forum=transactsql, но, похоже, не смог сделать все правильно. Вот таблица:

 TABLE OCCUPATIONS

Name    Occupation
Samantha    Doctor
Julia   Actor
Maria   Actor
Meera   Singer
Ashley  Professor
Ketty   Professor
Christeen   Professor
Jane    Actor
Jenny   Doctor
Priya   Singer

Задача состоит в том, чтобы получить выходные данные с колонками Доктор, Профессор, Певец или Актер (в таком порядке). Если у вас заканчиваются данные для одного или нескольких столбцов, введите NULL. Вот ожидаемый результат (скопированный непосредственно с сайта).

Jenny    Ashley     Meera  Jane
Samantha Christeen  Priya  Julia
NULL     Ketty      NULL   Maria

В качестве отступления, похоже, они хотят получить результаты без заголовков столбцов (я не уверен!).

Вот последняя итерация того, что я пробовал:

SELECT [Doctor], [Professor],[Singer], [Actor]
FROM
(SELECT [Name], [Occupation] from OCCUPATIONS) as pvtsource
PIVOT
( MAX([Name]) FOR [Occupation] IN ([Doctor], [Professor],[Singer], [Actor]) ) AS p

и это дает:

     Doctor Professor   Singer  Actor
Samantha    Ketty   Priya   Maria

Меня не удивляет этот неверный результат. В конце концов, я сказал в своем запросе MAX. Я предполагаю, что он просто выбирает имя MAX для каждой профессии в алфавитном порядке. Мария - более крупный актер, чем Джулия или Джейн, например, если вы основали ее на алфавите. Но когда я удаляю MAX, я получаю сообщение об ошибке («Неверный синтаксис ...»). Как это сделать?

Спасибо! Бонусные вопросы 1. Хорошие, нежные, статьи на PIVOT? Я ясно не получил это через мою толстую голову. В конце концов, я хочу делать более сложные пивоты, где я SUM или беру MAX. 2. Как отобразить результаты без заголовков столбцов? 3. Мне также было бы интересно узнать, как это сделать без PIVOT, если есть простой способ.

1 Ответ

2 голосов
/ 10 марта 2020

Вам необходимо «ПОДАВАТЬ» стержень с осью X, осью Y и значением. Мы создаем ключ строки с помощью dense_rank()

Пример

Declare @YourTable Table ([Name] varchar(50),[Occupation] varchar(50))  Insert Into @YourTable Values 
 ('Samantha','Doctor')
,('Julia','Actor')
,('Maria','Actor')
,('Meera','Singer')
,('Ashley','Professor')
,('Ketty','Professor')
,('Christeen','Professor')
,('Jane','Actor')
,('Jenny','Doctor')
,('Priya','Singer')

Select * 
 from (Select *
             ,RN = dense_rank() over (partition by occupation order by name)
        From  @YourTable
      ) src
 Pivot (max(Name) for Occupation in ([Doctor], [Professor],[Singer], [Actor]) ) pvt 

Возвращает

RN  Doctor      Professor   Singer  Actor
1   Jenny       Ashley      Meera   Jane
2   Samantha    Christeen   Priya   Julia
3   NULL        Ketty       NULL    Maria

ПРИМЕЧАНИЕ:

Если вы не хотите, чтобы RN в ваших результатах, вместо верхнего SELECT *, вы можете указать нужные столбцы

SELECT [Doctor], [Professor],[Singer], [Actor]
 From  (...) src
 Pivot (...) pvt

EDIT - Комментарий

Если вы выполните внутренний запрос

Select *
      ,RN = dense_rank() over (partition by occupation order by name)
 From  @YourTable
 Order By RN

Вы получите

Name        Occupation  RN
Jane        Actor       1
Jenny       Doctor      1
Ashley      Professor   1
Meera       Singer      1
Priya       Singer      2
Christeen   Professor   2
Samantha    Doctor      2
Julia       Actor       2
Maria       Actor       3
Ketty       Professor   3

RN станет осью Y, Оккупация станет X- Ось и имя это значение. Опорные точки по конструкции являются агрегатами, поэтому нам нужна только ось Y, чтобы выполнить группу по.

...