SQL枢轴列值

时间:2020-09-25 17:19:23

标签: mysql sql

Problem Statement

在OCCUPATIONS中的Occupation列中,使每个名称按字母顺序排序并显示在其对应的职业下方。 输出列标题分别为Doctor,Professor,Singer和Actor。

注意:当没有更多与职业相对应的名称时,输出NULL。

职业将仅包含以下值之一:医生,教授,歌手或演员。

样本输入

enter image description here

示例输出

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

我的解决方案:

select Doctor, Professor, Singer, Actor from
(
    select a.name, a.occupation, count(*) as row_num from Occupations a
    join Occupations b 
    on a.occupation=b.occupation and (a.name>=b.name)
    group by a.name, a.occupation
    order by row_num asc;
) as t
PIVOT
(
    max(name)
    for occupation in (Doctor, Professor, Singer, Actor)
)
as pvt;

错误:

第1行的错误1064(42000):您的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册以获取正确的语法,以在第7行的''附近使用

第7行:

order by row_num asc;

我正在尝试学习高级sql概念,到目前为止,我已经能够编写查询,但出现此错误。当我运行子查询时,它工作正常,并且得到一些输出,但是在使用数据透视后,出现了此错误。我不知道如何解决它,以及导致此错误的原因。

我想由pivot运算符而不使用row_number来完成此操作。

子查询:

select a.name, a.occupation, count(*) as row_num from Occupations a
.
.
order by row_num;

子查询输出:

Belvet Professor 1
Jane Singer 1
Jennifer Actor 1
Julia Doctor 1
Britney Professor 2
Priya Doctor 2
Ketty Actor 2
Jenny Singer 2
Maria Professor 3
Samantha Actor 3
Kristeen Singer 3
Meera Professor 4
Naomi Professor 5
Priyanka Professor 6

1 个答案:

答案 0 :(得分:1)

您可以使用窗口函数和条件聚合:

select
    rn,
    max(case when occupation = 'Doctor' then name end) doctor,
    max(case when occupation = 'Singer' then name end) singer,
    max(case when occupation = 'Actor'  then name end) actor
from (
    select t.*, row_number() over(partition by occupation order by name) rn
    from mytable t
)
group by rn

子查询按名称对具有相同占领的人员进行排名。然后,您可以使用该信息来生成行,并使用条件聚合来访问每个职业的相应名称。

没有窗口功能,情况有所不同。如果您的数据不是太大,则可以使用一个子查询来模拟行号:

select
    rn,
    max(case when occupation = 'Doctor' then name end) doctor,
    max(case when occupation = 'Singer' then name end) singer,
    max(case when occupation = 'Actor'  then name end) actor
from (
    select t.*, 
        (
            select count(*) 
            from mytable t1 
            where t1.occupation = t.occupation and t1.name <= t.name
        ) rn
    from mytable t
)
group by rn