如何在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