【问题标题】:SELECT data from 1st table whether exists or not in 2nd table but with conditions从第一个表中选择数据是否存在于第二个表中但有条件
【发布时间】:2015-08-03 02:37:14
【问题描述】:

我需要一些 sql/postgres 大师的帮助。我想要完成的是我有一张tracksgenresplaylists 的表格。我需要从表tracks 中选择它是否已经存在于track_playlists 中或不存在。我已经做过了。这是当前代码。

SELECT tr.*, MAX(tp.played) as last FROM tracks as tr 
LEFT JOIN track_genres as tg ON tr.trk_id = tg.trk_id 
LEFT JOIN track_playlists as tp ON tr.trk_id = tp.trk_id 
AND tp.mem_id=12345 AND tp.chn_id=9 
AND tp.played > EXTRACT(epoch from NOW() - INTERVAL '4 hours') 
AND (tr.artist != tp.artist AND tp.played > EXTRACT(epoch from NOW() - INTERVAL '1 hours'))
WHERE tg.rotation=2 GROUP BY tr.trk_id ORDER BY last ASC LIMIT 6

示例场景:

tracks

trk_id | artist  | title
-------------------------
1      | artist1 | title1
2      | artist1 | title2
3      | artist2 | title1
4      | artist3 | title1
5      | artist4 | title1
6      | artist5 | title1
7      | artist1 | title3
8      | artist6 | title1

track_genres

gen_id | trk_id | rotation
--------------------------
1      | 1       | 9 
2      | 2       | 9
3      | 3       | 2
4      | 4       | 3
5      | 5       | 9
6      | 6       | 2
7      | 7       | 10
8      | 8       | 9

track_playlists

pla_id | mem_id  | trk_id | chn_id | artist  | title | played
-------------------------------------------------------------

这是我正在处理的表格。目前,当用户启动时,他们的track_playlist 是空的。当他们选择一种流派时,它应该填充此表,但不是一次全部填充,因此是 Limit 子句,并且它需要根据此表中是否已经有歌曲为用户选择歌曲。如果没有任何歌曲,那么它会通过我正在尝试的选择查询来选择歌曲。随着歌曲的播放,当它要提取新歌曲时,它需要查看track_playlist 中已经存在哪些歌曲。如果歌曲已经在播放列表中,那么它应该跳过它,只为这个用户提取尚未在播放列表中的歌曲。一旦 all 歌曲最终出现在用户的播放列表中,它只需要检查 played timestamp 以查看该歌曲的最后播放时间是否大于 4 小时,并且它是 @987654341 的最旧曲目@(最近最少播放)而不是最近 1 小时内播放的艺术家。

我希望这更清楚一点。

我用这个答案来帮助我查询是否为空。

sql update data in 2nd db from 1st db only where table exists

【问题讨论】:

  • 请给我们一些示例数据以及您的预期结果,以便进一步澄清;)。
  • 你的问题有点难以解读,这可能是为什么还没有人破解它的原因。如果您提供示例表、数据和结果,甚至是 sqlfiddle,会更容易。 --- 现在我想说 and 是最近最少播放的曲目 不清楚并且没有反映在您的查询中,而且 AND (tr.artist != tp.artist AND tp.played > EXTRACT(epoch from NOW() - INTERVAL '1 hours')) 看起来不正确 - 您已经加入 trtptrk_id,但又说艺术家一定不一样?我认为您可能将太多东西组合成一个连接。

标签: sql postgresql postgresql-9.1


【解决方案1】:

我认为您将需要两个子查询: 每位艺术家的最后播放时间:

select artist, max(played) 
from track_playlists 
WHERE mem_id=12345 AND chn_id=9 
GROUP BY artist

每首曲目的最后播放时间:

select trk_id, max(played) 
from track_playlists 
WHERE mem_id=12345 AND chn_id=9 
GROUP BY trk_id

然后应用条件将您的曲目和流派表加入到它们中(您将需要使用 LEFT JOIN 以确保始终包含新的曲目和艺术家)。您还需要使用 EXISTS 对最后播放的艺术家进行额外检查,如下所示:

SELECT * FROM(
SELECT tr.*, tl.track_last_played, al.artist_last_played,
ROW_NUMBER() OVER(PARTITION BY tr.artist) rn
FROM tracks as tr 
LEFT JOIN track_genres as tg ON tr.trk_id = tg.trk_id 
LEFT JOIN (select artist, max(played) as artist_last_played 
           from track_playlists 
           WHERE mem_id=12345 AND chn_id=9
           GROUP BY artist) as al 
   ON tr.artist = al.artist
LEFT JOIN (select trk_id, max(played) as track_last_played 
           from track_playlists 
           WHERE mem_id=12345 AND chn_id=9
           GROUP BY trk_id) as tl 
   ON tr.trk_id = tl.trk_id 
WHERE (tl.track_last_played IS NULL OR tl.track_last_played < EXTRACT(epoch from NOW() - INTERVAL '4 hours') )
AND NOT EXISTS (SELECT 1 FROM track_playlists WHERE mem_id=12345 AND chn_id=9 
                AND artist = tr.artist                
                AND played > EXTRACT(epoch from NOW() - INTERVAL '1 hours'))
) a
WHERE rn = 1
ORDER BY track_last_played, artist_last_played ASC 

SQL Fiddle

【讨论】:

  • 感谢您的尝试。我没有看到 mem_id 的子句。它是用户特定的。 AND tp.mem_id=12345 AND tp.chn_id=9 究竟会去哪里?
  • 那么,曲目需要在track_playlists 中才能播放?
  • 是的,正确。当您回答时,为了清楚起见,我正在更新问题。查看表格示例下方的编辑。
  • 我做了一些测试,但它并没有像我预期的那样正常工作。我将限制更改为 1,然后将该查询放入 foreach 循环中,它给了我artist1, artist1, artist1, artist4, artist6, artist4,您可以看到它重复了 2 个艺术家。由于 Artist1 已经输入到表中,它不应该在下一次迭代中选择那个。这有意义吗?
  • 我在想它可能需要某种类型的 Not exists 子句,但确定这是否可行。
猜你喜欢
  • 1970-01-01
  • 2023-03-24
  • 2021-12-12
  • 1970-01-01
  • 2012-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多