SQL Текстовые значения сервера - PullRequest
2 голосов
/ 12 февраля 2020

Я практикую пивот. И у меня есть таблица с данными имени и профессии (код для генерации образца ниже). Мне нужно поместить Профессии в столбцы и расположить под каждым занятием имена. Ноль в порядке.

Я видел несколько постов, и этот один - это то, что мне нужно, но после адаптации к моим данным он извлекает только 1 строку данных.

Вот код для генерации примера и фактического сводного кода. Как я могу исправить эту ошибку?

declare @occupations table (ename nvarchar(10), occupation nvarchar(10) )
insert @occupations
values 
('John','Doctor'),('Mary','Doctor'),('Jack','Doctor'),('Anna','Doctor'),
('Jim','Singer'),('Kate','Singer'),('Helen','Actor'),('Paco','Singer')

SELECT [Doctor] Doctor, [Singer] Singer, [Actor] Actor
FROM @occupations
PIVOT
  (min(ename)  
    FOR occupation IN ([Doctor],[Singer], [Actor])  
  )AS pp

Я получаю такой результат:

 Doctor Singer Actor
 Anna   Jim    Helen    

Должно быть больше строк, чтобы включить все имена. То есть вы можете увидеть в заявлении о том, что, например, 4 врача. Так должно быть 8 строк с некоторыми нулями.

Ответы [ 3 ]

2 голосов
/ 12 февраля 2020

SQL Выполнение скрипта

MS SQL Настройка схемы сервера 2017 :

create table occupations (ename nvarchar(10), occupation nvarchar(10) )
insert into occupations(ename,occupation)values ('John','Doctor'),('Mary','Doctor'),('Jack','Doctor'),('Anna','Doctor'),
('Jim','Singer'),('Kate','Singer'),('Helen','Actor'),('Paco','Singer')

** Запрос **:

WITH CTE AS (
  SELECT *,
  (case when occupation like 'singer' then ename end) AS Singer,
    (case when occupation like 'doctor' then ename end) AS Doctor,
    (case when occupation like 'Actor' then ename end) AS Actor,
  ROW_Number() OVER (PARTITION BY occupation Order By ename) as rn
  from occupations
  group by ename,occupation)

  select max(Singer) AS Singer,max(Doctor) AS Doctor, max(Actor) AS Actor
  from cte
  where rn=1 

Результаты :

| Singer | Doctor | Actor |
|--------|--------|-------|
|    Jim |   Anna | Helen |
1 голос
/ 12 февраля 2020

Вы также можете сделать его динамическим c, чтобы автоматически выбрать все столбцы

create table #occupations  (ename nvarchar(10), occupation nvarchar(10) )
insert   #occupations
values 
('John','Doctor'),('Mary','Doctor'),('Jack','Doctor'),('Anna','Doctor'),
('Jim','Singer'),('Kate','Singer'),('Helen','Actor'),('Paco','Singer') ;


DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(occupation) 
            FROM #occupations 
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'');

set @query = 'SELECT * FROM #occupations
                    PIVOT
                        (min(ename)  
                FOR occupation IN ('+ @cols +')  
              )AS pp'
exec (@query) 
drop table #occupations
0 голосов
/ 12 февраля 2020

Если вам нужны все строки, просто добавьте уникальный ключ, например row_number ()

Пример

SELECT [Doctor] Doctor, [Singer] Singer, [Actor] Actor
FROM (
       Select *
             ,rn=row_number() over(order by ename) 
        from @occupations
     ) src
PIVOT
  (min(ename)  
    FOR occupation IN ([Doctor],[Singer], [Actor])  
  )AS pp

Возвращает

Doctor  Singer  Actor
Anna    NULL    NULL
NULL    NULL    Helen
Jack    NULL    NULL
NULL    Jim     NULL
John    NULL    NULL
NULL    Kate    NULL
Mary    NULL    NULL
NULL    Paco    NULL
...