一对多 - 值成为结果列

问题描述 投票:0回答:2

假设我有两个一对多相关的表:

Person:
  - name
  - age
  - phone
Attributes:
  - fk
  - field
  - value

例如

人:

id 名字 年龄 电话
1 约翰 18
null
2 22 1234567890
3 琳达 31 9876543210

属性:

id fk 价值
1 1 头发 棕色
2 1 眼睛 蓝色
3 2 头发 黑色
4 3 高度 6

是否可以创建一个结果如下所示的查询:

名字 年龄 电话 头发 眼睛 高度
约翰 18
null
棕色 蓝色
null
22 1234567890 黑色
null
null
琳达 31 9876543210
null
null
6
sql mysql doctrine-orm doctrine
2个回答
0
投票

不幸的是,据我所知,MySQL 不支持

pivot
,但如果这不需要动态数量的属性,您可以通过
Attributes
自联接
left join
,并过滤对属性的联接需要:

select p.name
    , p.age
    , p.phone
    , hair.value
    , eye.value
    , height.value
from Person p
left join Attributes hair
    on p.id = hair.fk
    and hair.field = 'hair'
 left join Attributes eye
    on p.id = eye.fk
    and eye.field = 'eye'
 left join Attributes height
    on p.id = height.fk
    and height.field = 'height'

如果您确实需要动态数量的属性,则可以创建一个准备好的语句,但我没有现成的示例。


0
投票

这是使用

conditional aggregation
的解决方案。

create table person (
  id integer, 
  name varchar(10), 
  age integer, 
  phone varchar(10)
  );
  
insert into person values 
(1, 'John', 18, null), 
(2, 'Sue', 22, '1234567890'), 
(3, 'Linda', 31, '9876543210'), 
(4, 'Seymore', 78, null);

create table attributes (
  id integer, 
  fk integer, 
  field varchar(20), 
  value varchar(20)
  );
  
insert into attributes values 
(1, 1, 'hair', 'brown'), 
(2, 1, 'eyes', 'blue'), 
(3, 2, 'hair', 'black'), 
(4, 3, 'height', '6');

select  
  p.name, 
  p.age, 
  p.phone, 
  max(case when a.field = 'hair' then a.value else null end) as hair, 
  max(case when a.field = 'eyes' then a.value else null end) as eyes, 
  max(case when a.field = 'height' then a.value else null end) as height
from person p
left join attributes a
  on p.id = a.fk
group by p.name, p.age, p.phone;
名字 年龄 电话 头发 眼睛 高度
约翰 18 棕色 蓝色
22 1234567890 黑色
琳达 31 9876543210 6
西摩尔 78

在 DB Fiddle 上查看

© www.soinside.com 2019 - 2024. All rights reserved.