如何将 select hasMany 关系作为列名
How to select hasMany relation as a column name
我有 2 个 table。
- 电影
- movie_meta
电影table
| id | name |
---------------------
| 1 | Harry Potter |
| 2 | Joker |
| 3 | Need For Speed|
movie_meta table
| id | movie_id | key | value |
---------------------------------------------
| 1 | 1 | country | USA |
| 2 | 1 | genre | Horror & Sci-Fi |
| 3 | 1 | actor | Daniel Radcliffe |
我想达到的效果是这样的
| id | name | country | genre | actor |
--------------------------------------------------------------------
| 1 | Harry Potter | USA | Horror & Sci-Fi | Daniel Radcliffe |
movie_meta table行数无限制。那么,如何 select ?
谢谢
一种方法使用条件聚合。另一个使用多个 join
s。对于此示例,两者在性能方面可能相似:
select m.*, mmc.value as country, mmg.value as genre, mma.value as actor
from movies m left join
movie_meta mmc
on mmc.movie_id = m.id = and mmc.key = 'country' left join
movie_meta mma
on mma.movie_id = m.id = and mma.key = 'actor' left join
movie_meta mmg
on mmg.movie_id = m.id = and mmg.key = 'genre' ;
请注意,您的示例每部电影只有一个演员和一个流派。在现实世界中,这两者都可以有多个值。
您可以加入movie_meta
三次:
select
m.*,
c.value country,
g.value genre,
a.value actor
from movie m
inner join movie_meta c on c.movie_id = m.id and c.key = 'country'
inner join movie_meta g on g.movie_id = m.id and g.key = 'genre'
inner join movie_meta a on a.movie_id = m.id and a.key = 'actor'
为了性能,您需要在 movie_meta(movie_id, key)
上建立索引。
如果元 table 可能缺少其中一个属性,您可以将 inner join
改为 left join
。
或者你可以进行条件聚合(这样更简洁但效率可能较低):
select
m.id,
m.name,
max(case when x.key = 'country' then value end) country,
max(case when x.key = 'genre' then value end) genre,
max(case when x.key = 'actor' then value end) actor
from movie m
inner join movie_meta x on x.movie_id = m.id
group by m.id, m.name
我有 2 个 table。
- 电影
- movie_meta
电影table
| id | name |
---------------------
| 1 | Harry Potter |
| 2 | Joker |
| 3 | Need For Speed|
movie_meta table
| id | movie_id | key | value |
---------------------------------------------
| 1 | 1 | country | USA |
| 2 | 1 | genre | Horror & Sci-Fi |
| 3 | 1 | actor | Daniel Radcliffe |
我想达到的效果是这样的
| id | name | country | genre | actor |
--------------------------------------------------------------------
| 1 | Harry Potter | USA | Horror & Sci-Fi | Daniel Radcliffe |
movie_meta table行数无限制。那么,如何 select ? 谢谢
一种方法使用条件聚合。另一个使用多个 join
s。对于此示例,两者在性能方面可能相似:
select m.*, mmc.value as country, mmg.value as genre, mma.value as actor
from movies m left join
movie_meta mmc
on mmc.movie_id = m.id = and mmc.key = 'country' left join
movie_meta mma
on mma.movie_id = m.id = and mma.key = 'actor' left join
movie_meta mmg
on mmg.movie_id = m.id = and mmg.key = 'genre' ;
请注意,您的示例每部电影只有一个演员和一个流派。在现实世界中,这两者都可以有多个值。
您可以加入movie_meta
三次:
select
m.*,
c.value country,
g.value genre,
a.value actor
from movie m
inner join movie_meta c on c.movie_id = m.id and c.key = 'country'
inner join movie_meta g on g.movie_id = m.id and g.key = 'genre'
inner join movie_meta a on a.movie_id = m.id and a.key = 'actor'
为了性能,您需要在 movie_meta(movie_id, key)
上建立索引。
如果元 table 可能缺少其中一个属性,您可以将 inner join
改为 left join
。
或者你可以进行条件聚合(这样更简洁但效率可能较低):
select
m.id,
m.name,
max(case when x.key = 'country' then value end) country,
max(case when x.key = 'genre' then value end) genre,
max(case when x.key = 'actor' then value end) actor
from movie m
inner join movie_meta x on x.movie_id = m.id
group by m.id, m.name