加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Postgresql 9.3 – array_agg challenge

发布时间:2020-12-13 16:08:55 所属栏目:百科 来源:网络整理
导读:我正在尝试理解 Postgresql 9.3中的array_agg函数.我为每个可能有兴趣参与的人提供了一个有趣的例子. 20世纪80年代的任何一部美国电影迷都可能熟悉一起出现在很多热门影片中的“小伙子”.在wikipedia上使用关于brat pack影片的信息,我创建了表格,当它们连接
我正在尝试理解 Postgresql 9.3中的array_agg函数.我为每个可能有兴趣参与的人提供了一个有趣的例子.

20世纪80年代的任何一部美国电影迷都可能熟悉一起出现在很多热门影片中的“小伙子”.在wikipedia上使用关于brat pack影片的信息,我创建了表格,当它们连接在一起时,可以告诉我们谁在彼此工作 – 如果我们有正确的查询!

/*
See:  http://en.wikipedia.org/wiki/Brat_Pack_(actors)
*/

CREATE TABLE actor(
    id SERIAL PRIMARY KEY,name VARCHAR(50)
);
insert into actor(name) values ('Emilio Estevez'),('Anthony Michael Hall'),('Rob Lowe'),('Andrew McCarthy'),('Demi Moore'),('Judd Nelson'),('Molly Ringwald'),('Ally Sheedy')

CREATE TABLE movie(
    id SERIAL PRIMARY KEY,title VARCHAR(200)
);
insert into movie(title) values ('The Outsiders'),('Class'),('Sixteen Candles'),('Oxford Blues'),('The Breakfast Club'),('St. Elmos Fire'),('Pretty in Pink'),('Blue City'),('About Last Night'),('Wisdom'),('Fresh Horses'),('Betsys Wedding'),('Hail Caesar');

CREATE TABLE movie_brats(
    id SERIAL PRIMARY KEY,movie_id INT REFERENCES movie(id),actor_id INT REFERENCES actor(id)
);
insert into movie_brats(movie_id,actor_id) values (1,1),(1,3),(2,4),(3,2),7),(4,8),(5,6),(6,5),(7,(8,(9,(10,(11,(12,(13,6);

查询:显示brat包的每个成员使用的不同列表,在两列中按名称排序

Name                      Worked With
 ----------------------------------------------------------------------------------------------------------------
Emelio Estevez       |  Emilio Estevez,Anthony Michael Hall,Rob Lowe,Andrew McCarthy,Demi Moore,Judd Nelson,Molly Ringwald,Ally Sheedy
*/

我破碎的查询:

select a1.name,array_to_string(array_agg(a2.name),',') as Co_Stars
from actor a1,actor a2,movie m,movie_brats mb
where 
    m.id = mb.movie_id
    and a1.id = mb.actor_id
    and a2.id = mb.actor_id
group by a1.id

解决方法

SQL Fiddle

with v as (
    select
        a.id as actor_id,a.name as actor_name,m.id as m_id
    from
        actor a
        inner join
        movie_brats mb on a.id = mb.actor_id
        inner join
        movie m on m.id = mb.movie_id
)
select
    v1.actor_name as "Name",string_agg(
        distinct v2.actor_name,' order by v2.actor_name
    ) as "Worked With"
from
    v v1
    left join
    v v2 on v1.m_id = v2.m_id and v1.actor_id != v2.actor_id
group by 1
order by 1

如果它们在多个电影中一起工作,则上面的不同聚合对于不显示重复的名称是必要的.

左连接是必要的,不能抑制不与列表中任何其他人一起工作的actor,就像内连接一样.

如果你想展示他们合作的电影:SQL Fiddle

with v as (
    select
        a.id as actor_id,m.id as m_id,m.title as title
    from
        actor a
        inner join
        movie_brats mb on a.id = mb.actor_id
        inner join
        movie m on m.id = mb.movie_id
)
select
    a1 as "Name",string_agg(
        format('%s (in %s)',a2,title),'
        order by format('%s (in %s)',title)
    ) as "Worked With"
from (
    select 
        v1.actor_name as a1,v2.actor_name as a2,string_agg(v1.title,' order by v1.title) as title    
    from
        v v1
        left join
        v v2 on v1.m_id = v2.m_id and v1.actor_id != v2.actor_id
    group by 1,2
) s
group by 1
order by 1

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读