MySQL表“;“支点”;不创建表/视图:作为标题的唯一列值
我有这个“职业”两列表,包含多个人的姓名和职业。职业是已知的,只能是“开发者”、“工程师”、“医生”、“音乐家”MySQL表“;“支点”;不创建表/视图:作为标题的唯一列值,mysql,sql,database,pivot-table,Mysql,Sql,Database,Pivot Table,我有这个“职业”两列表,包含多个人的姓名和职业。职业是已知的,只能是“开发者”、“工程师”、“医生”、“音乐家” Name | Occupation Dan | Developer Martin | Doctor Sam | Engineer Andre | Musician Tom | Engineer 其目的是获得如下信息: Doctor | Engineer | Developer | Musician Martin | Sam | Dan
Name | Occupation
Dan | Developer
Martin | Doctor
Sam | Engineer
Andre | Musician
Tom | Engineer
其目的是获得如下信息:
Doctor | Engineer | Developer | Musician
Martin | Sam | Dan | Andre
NULL | Tom | NULL | NULL
所有列应按字母顺序排列
关于如何使用MySQL实现这一点(无需创建表和视图),你们有什么建议吗
非常感谢 这是一个难题,但您可以使用变量和聚合:
select max(doctor) as doctor,
max(engineer) as engineer,
max(developer) as developer,
max(musician) as musician
from ((select name as doctor, null as engineer, null as developer, null as musician,
(@rnd := @rnd + 1) as rn
from t cross join
(select @rnd := 0) as params
where occupation = 'doctor'
) union all
(select null as doctor, name as engineer, null as developer, null as musician,
(@rne := @rne + 1) as rn
from t cross join
(select @rne := 0) as params
where occupation = 'engineer'
) union all
(select null as doctor, null as engineer, name as developer, null as musician,
(@rnv := @rnv + 1) as rn
from t cross join
(select @rnv := 0) as params
where occupation = 'developer'
) union all
(select null as doctor, null as engineer, null as developer, name as musician,
(@rnm := @rnm + 1) as rn
from t cross join
(select @rnm := 0) as params
where occupation = 'musician'
) union all
) o
group by rn;
这是一个难题,但您可以使用变量和聚合:
select max(doctor) as doctor,
max(engineer) as engineer,
max(developer) as developer,
max(musician) as musician
from ((select name as doctor, null as engineer, null as developer, null as musician,
(@rnd := @rnd + 1) as rn
from t cross join
(select @rnd := 0) as params
where occupation = 'doctor'
) union all
(select null as doctor, name as engineer, null as developer, null as musician,
(@rne := @rne + 1) as rn
from t cross join
(select @rne := 0) as params
where occupation = 'engineer'
) union all
(select null as doctor, null as engineer, name as developer, null as musician,
(@rnv := @rnv + 1) as rn
from t cross join
(select @rnv := 0) as params
where occupation = 'developer'
) union all
(select null as doctor, null as engineer, null as developer, name as musician,
(@rnm := @rnm + 1) as rn
from t cross join
(select @rnm := 0) as params
where occupation = 'musician'
) union all
) o
group by rn;
这将在MySql 8.0中工作:
with occup as (
select
case when o.occupation = 'Doctor' then o.Name end as Doctor,
case when o.occupation = 'Engineer' then o.Name end as Engineer,
case when o.occupation = 'Developer' then o.Name end as Developer,
case when o.occupation = 'Musician' then o.Name end as Musician
from occupations o
),
doctors as (
select ROW_NUMBER() OVER (
ORDER BY case when occup.Doctor is null then 1 else 0 end
) as rn, occup.Doctor from occup
),
engineers as (
select ROW_NUMBER() OVER (
ORDER BY case when occup.Engineer is null then 1 else 0 end
) as rn, occup.Engineer from occup
),
developers as (
select ROW_NUMBER() OVER (
ORDER BY case when occup.Developer is null then 1 else 0 end
) as rn, occup.Developer from occup
),
musicians as (
select ROW_NUMBER() OVER (
ORDER BY case when occup.Musician is null then 1 else 0 end
) as rn, occup.Musician from occup
)
select doctors.Doctor, engineers.Engineer, developers.Developer, musicians.Musician
from doctors
inner join engineers on doctors.rn = engineers.rn
inner join developers on engineers.rn = developers.rn
inner join musicians on musicians.rn = developers.rn
WHERE coalesce(doctors.Doctor, engineers.Engineer, developers.Developer, musicians.Musician) IS NOT NULL;
请参阅这将在MySql 8.0中工作:
with occup as (
select
case when o.occupation = 'Doctor' then o.Name end as Doctor,
case when o.occupation = 'Engineer' then o.Name end as Engineer,
case when o.occupation = 'Developer' then o.Name end as Developer,
case when o.occupation = 'Musician' then o.Name end as Musician
from occupations o
),
doctors as (
select ROW_NUMBER() OVER (
ORDER BY case when occup.Doctor is null then 1 else 0 end
) as rn, occup.Doctor from occup
),
engineers as (
select ROW_NUMBER() OVER (
ORDER BY case when occup.Engineer is null then 1 else 0 end
) as rn, occup.Engineer from occup
),
developers as (
select ROW_NUMBER() OVER (
ORDER BY case when occup.Developer is null then 1 else 0 end
) as rn, occup.Developer from occup
),
musicians as (
select ROW_NUMBER() OVER (
ORDER BY case when occup.Musician is null then 1 else 0 end
) as rn, occup.Musician from occup
)
select doctors.Doctor, engineers.Engineer, developers.Developer, musicians.Musician
from doctors
inner join engineers on doctors.rn = engineers.rn
inner join developers on engineers.rn = developers.rn
inner join musicians on musicians.rn = developers.rn
WHERE coalesce(doctors.Doctor, engineers.Engineer, developers.Developer, musicians.Musician) IS NOT NULL;
请参阅的可能的副本查看SQL代码有多难看?在应用程序代码中执行它!完全同意@RickJames。这不仅是因为代码很难看,而且缺乏灵活性。如果职业超过4个,你会怎么做?您需要添加多少代码?在sql中执行此操作的唯一原因可能是,如果表中的数据量非常大。@forpas-如果存在“非常大”的数据量,则输出将是“非常大”。在这一点上,我会严肃地批评UI决定有4个非常高的列表。@RickJames你不认为大量的数据应该在适当的位置进行操作,只将结果获取到终端(pc),而不是获取整个数据并在那里进行过滤/处理吗?可能的重复看看SQL代码有多难看?在应用程序代码中执行它!完全同意@RickJames。这不仅是因为代码很难看,而且缺乏灵活性。如果职业超过4个,你会怎么做?您需要添加多少代码?在sql中执行此操作的唯一原因可能是,如果表中的数据量非常大。@forpas-如果存在“非常大”的数据量,则输出将是“非常大”。在这一点上,我会严肃地批评UI决定有4个非常高的列表。@RickJames你不认为大量数据应该在适当的位置进行操作,只将结果获取到终端(pc),而不是获取整个数据并在那里进行过滤/处理吗?