从第一个表中选择数据是否存在于第二个表中但是有条件

时间:2015-08-03 02:37:15

标签: sql postgresql postgresql-9.1

我需要一些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小时,并且timestamp(最近最少播放)最古老的曲目,而不是最近1小时播放的艺术家。

我希望这更清楚一点。

我用这个答案来帮助我查询空或不。

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

1 个答案:

答案 0 :(得分:2)

我认为你需要两个子查询: 每个艺术家的最后一次演出时间:

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