如何在sql server中使用pivot(无聚合)?

如何在sql server中使用pivot(无聚合)?,sql,sql-server,database,Sql,Sql Server,Database,请帮我解决这个问题: 将为您提供一个包含两列的表: 列是以下内容之一: Doctor Professor Singer Actor 编写查询以输出相应occ下的名称。格式如下: +--------+-----------+--------+------+ | Doctor | Professor | Singer | Actor| +--------+-----------+--------+------+ 姓名必须按字母顺序排列 样本输入 Name Occupation

请帮我解决这个问题: 将为您提供一个包含两列的表: 列是以下内容之一:

Doctor
Professor
Singer
Actor
编写查询以输出相应occ下的名称。格式如下:

+--------+-----------+--------+------+

| Doctor | Professor | Singer | Actor|

+--------+-----------+--------+------+
姓名必须按字母顺序排列

样本输入

Name        Occupation
Meera       Singer
Ashely      Professor
Ketty       Professor
Christeen   Professor
Jane        Actor
Jenny       Doctor
Priya       Singer    
样本输出

Jenny    Ashley     Meera  Jane

Samantha Christeen  Priya  Julia

NULL     Ketty      NULL   Maria

当没有更多与职业对应的姓名时,打印“NULL”

我尝试使用:

SELECT *
FROM
(
SELECT [Name], [Occupation] 
FROM occupations 
) AS source
PIVOT
(
    max([Name])
    FOR [occupation] IN ([Doctor], [Professor], [Singer], [Actor]) 
) as pvt;
这将提供以下输出:

Priya Priyanka Kristeen Samantha 

如何修复它?

您只需要根据每个名称的职业和字母顺序为其指定一个行号。。然后在透视查询中包括该行号

CREATE TABLE Occupations (
     NAME VARCHAR(MAX),
     Occupation VARCHAR(MAX)
    )
INSERT  INTO Occupations
VALUES
        ('Samantha','Doctor'),
        ('Julia','Actor'),
        ('Maria','Actor'),
        ('Meera','Singer'),
        ('Ashley','Professor'),
        ('Ketty','Professor'),
        ('Christeen','Professor'),
        ('Jane','Actor'),
        ('Jenny','Doctor'),
        ('Priya','Singer');

SELECT
    [Doctor],
    [Professor],
    [Singer],
    [Actor]
FROM
    (SELECT 
         ROW_NUMBER() OVER (PARTITION BY Occupation ORDER BY Name) rn,
         [Name],
         [Occupation] 
     FROM 
         Occupations
    ) AS source 
PIVOT
    MAX(Name) FOR [occupation] IN ([Doctor],[Professor],[Singer],[Actor]) as pvt
ORDER BY rn


DROP TABLE Occupations

我在Oracle中尝试过这一点,似乎更容易理解:

SELECT min(Doctor), min(Professor), min(Singer), min(Actor)
FROM
( Select
ROW_NUMBER() OVER (PARTITION BY Occupation order by Name) rn, 
CASE 
WHEN Occupation = 'Doctor' then Name
end as Doctor,
CASE 
WHEN Occupation = 'Professor' then Name
end as Professor,
CASE 
WHEN Occupation = 'Singer' then Name
end as Singer,
CASE 
WHEN Occupation = 'Actor' then Name
end as Actor
from OCCUPATIONS
order by Name) a
group by rn
order by rn;

下面是答案的MYSQL版本。有点困难,因为HACKERRANK.com中没有完整的外部连接

SET @r1=0, @r2 = 0, @r3 = 0, @r4 = 0;

SELECT t1.name, t2.name, t3.name, t4.name
FROM

(SELECT 
    (@r1:=@r1 + 1) AS num1, 
    Name
FROM
    Occupations
    WHERE Occupation = 'Doctor'
ORDER BY Name) as t1

RIGHT JOIN

(SELECT 
    (@r2:=@r2 + 1) AS num2, 
    Name
FROM
    Occupations
    WHERE Occupation = 'Professor'
ORDER BY Name) as t2

ON t1.num1 = t2.num2

LEFT JOIN

(SELECT 
    (@r3:=@r3 + 1) AS num3, 
    Name
FROM
    Occupations
    WHERE Occupation = 'Singer'
ORDER BY Name) as t3

ON t2.num2 = t3.num3

LEFT JOIN

(SELECT 
    (@r4:=@r4 + 1) AS num4, 
    Name
FROM
    Occupations
    WHERE Occupation = 'Actor'
ORDER BY Name) as t4

ON t2.num2 = t4.num4

为什么需要这样做?作为一般原则,使用SQL格式化用于显示的数据是一种代码味道。这种结构对数据库不友好,通常应该在应用程序中推送到表示层,而不是在数据层中完成。将其移出数据库有助于确保您的代码不会陷入困境,您需要在这种格式的基础上进一步开发SQL。相反,以关系化/规范化的形式保存数据库的输出,这对未来更具适应性/可维护性/灵活性。@MatBailie我也这么想,但这是一个面试问题。¯_(ツ)_/“”您不必创建CTE,只需在select中列出列,而不用使用“select*”@JamieD77您能解释一下
行数()的必要性吗?
@Rookie_123 pivot基本上会对所有未聚合的数据进行分组。.添加行数会给每个名称另一个“分组”,使它们按职业区分开来,因此MAX()聚合不是每个职业只有一个名字,而是每个职业有一个名字,行号。你从这里得到:……记住链接到源代码!!@mahesh不要只是复制和粘贴。还要解释代码
SELECT [Doctor], [Professor], [Singer], [Actor] FROM   
(
    SELECT ROW_NUMBER() OVER (PARTITION BY Occupation ORDER BY Name) ROW_NO, 
    ISNULL(NULL,Name) as Name, Occupation
    FROM Occupations
) AS t 
PIVOT(
    MAX(Name)
    FOR Occupation IN (
        [Doctor], 
        [Professor], 
        [Singer], 
        [Actor]
    )
) AS pivot_table
ORDER BY ROW_NO;

SET @r1=0, @r2 = 0, @r3 = 0, @r4 = 0;

SELECT t1.name, t2.name, t3.name, t4.name
FROM

(SELECT 
    (@r1:=@r1 + 1) AS num1, 
    Name
FROM
    Occupations
    WHERE Occupation = 'Doctor'
ORDER BY Name) as t1

RIGHT JOIN

(SELECT 
    (@r2:=@r2 + 1) AS num2, 
    Name
FROM
    Occupations
    WHERE Occupation = 'Professor'
ORDER BY Name) as t2

ON t1.num1 = t2.num2

LEFT JOIN

(SELECT 
    (@r3:=@r3 + 1) AS num3, 
    Name
FROM
    Occupations
    WHERE Occupation = 'Singer'
ORDER BY Name) as t3

ON t2.num2 = t3.num3

LEFT JOIN

(SELECT 
    (@r4:=@r4 + 1) AS num4, 
    Name
FROM
    Occupations
    WHERE Occupation = 'Actor'
ORDER BY Name) as t4

ON t2.num2 = t4.num4