假设我有两个一对多相关的表:
Person:
- name
- age
- phone
Attributes:
- fk
- field
- value
例如
人:
id | 名字 | 年龄 | 电话 |
---|---|---|---|
1 | 约翰 | 18 |
|
2 | 苏 | 22 | 1234567890 |
3 | 琳达 | 31 | 9876543210 |
属性:
id | fk | 场 | 价值 |
---|---|---|---|
1 | 1 | 头发 | 棕色 |
2 | 1 | 眼睛 | 蓝色 |
3 | 2 | 头发 | 黑色 |
4 | 3 | 高度 | 6 |
是否可以创建一个结果如下所示的查询:
名字 | 年龄 | 电话 | 头发 | 眼睛 | 高度 |
---|---|---|---|---|---|
约翰 | 18 |
|
棕色 | 蓝色 |
|
苏 | 22 | 1234567890 | 黑色 |
|
|
琳达 | 31 | 9876543210 |
|
|
6 |
不幸的是,据我所知,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'
如果您确实需要动态数量的属性,则可以创建一个准备好的语句,但我没有现成的示例。
这是使用
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 |