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),而不是获取整个数据并在那里进行过滤/处理吗?