Sql 用有限的行左连接

Sql 用有限的行左连接,sql,postgresql,Sql,Postgresql,我有以下情况。我有三张桌子:艺术家、歌曲和统计数据。我想创建一个查询,显示每个艺术家最近的10首歌曲被播放了多少次。目前我有以下几点: SELECT artists.id, COALESCE(SUM(stats.plays), 0) FROM artists LEFT JOIN ( SELECT id FROM songs as inner_songs WHERE inner_songs.artist_id = artists.id ORDER BY pu

我有以下情况。我有三张桌子:艺术家、歌曲和统计数据。我想创建一个查询,显示每个艺术家最近的10首歌曲被播放了多少次。目前我有以下几点:

SELECT artists.id, COALESCE(SUM(stats.plays), 0)

FROM artists

LEFT JOIN (
    SELECT id

    FROM songs as inner_songs
    WHERE inner_songs.artist_id = artists.id

    ORDER BY published_at DESC

    LIMIT 10
) AS songs

LEFT JOIN stats
ON stats.song_id = songs.id

GROUP BY artists.id
我得到以下错误:

HINT:  There is an entry for table "artsis", but it cannot be referenced from this part of the query.

现在我明白了我不能在deleft join中使用artists.id,但问题仍然存在。如何进行此查询?

您可以通过两种不同的方式进行查询:

横向连接:

SELECT artists.id, COALESCE(SUM(stats.plays), 0)
FROM artists
  LEFT JOIN LATERAL (
      SELECT id, artist_id
      FROM songs as inner_songs
      WHERE artist_id = artists.id
      ORDER BY published_at DESC
      LIMIT 10
  ) AS songs ON songs.artist_id = artists.id
  LEFT JOIN stats ON stats.song_id = songs.id
GROUP BY artists.id;
也可以在派生表中使用窗口函数:

SELECT artists.id, COALESCE(SUM(stats.plays), 0)
FROM artists
  LEFT JOIN (
      SELECT id, 
             artist_id, 
             row_number() over (partition by artist_id order by published_at) as rn
      FROM songs
  ) AS songs ON songs.artist_id = artists.id AND rn <= 10
  LEFT JOIN stats ON stats.song_id = songs.id
GROUP BY artists.id;

使用横向连接的解决方案可能更快

您可以通过两种不同的方式实现:

横向连接:

SELECT artists.id, COALESCE(SUM(stats.plays), 0)
FROM artists
  LEFT JOIN LATERAL (
      SELECT id, artist_id
      FROM songs as inner_songs
      WHERE artist_id = artists.id
      ORDER BY published_at DESC
      LIMIT 10
  ) AS songs ON songs.artist_id = artists.id
  LEFT JOIN stats ON stats.song_id = songs.id
GROUP BY artists.id;
也可以在派生表中使用窗口函数:

SELECT artists.id, COALESCE(SUM(stats.plays), 0)
FROM artists
  LEFT JOIN (
      SELECT id, 
             artist_id, 
             row_number() over (partition by artist_id order by published_at) as rn
      FROM songs
  ) AS songs ON songs.artist_id = artists.id AND rn <= 10
  LEFT JOIN stats ON stats.song_id = songs.id
GROUP BY artists.id;

使用横向连接的解决方案可能更快

太棒了!如果你想把它作为一个答案发布,我会给它一个星号@a_horse_,并加上_no_name太棒了!如果你想把它作为一个答案发布,我会给它一个星号@a_horse_,上面写着“不”!这是最好的!