0

我加入了一个表格,将歌曲加入流派。该表有一个“来源”列,用于标识找到该流派的位置。流派可以从博客、艺术家、标签和帖子中找到。

所以,

songs | song_genre                 | genres 
id    | song_id, source, genre_id  | id

我想要构建的是一个类似这样的歌曲 SELECT 查询,因为我已经有一个genre_id:

IF exists song_genre with source='artist' AND a song_genre with source='blog'
OR exists song_genre with source='artist' AND a song_genre with source='post'
OR exists song_genre with source='tag'

我打算通过做一堆连接来做到这一点,但我确信我做得不是很好。

使用 Postgres 9.1。

4

2 回答 2

3

kgu87 的查询是正确的,但可能会产生一个相对昂贵的计划,其中包含对子选择的大量计数。case所有这些计数都可以通过在源上 s 和 a的流派表上一次通过来累积group by song_id。如果没有样本数据,很难说这是否更快,但我怀疑它是可能的。我认为无论如何它更简单。

select g.song_id
from song_genre g
group by g.song_id
having
  ( sum(case when g.source = 'tag' then 1 else 0 end) > 0 )
  or
  ( sum(case when g.source = 'artist' then 1 else 0 end) > 0
    and (
      sum(case when g.source = 'blog' then 1 else 0 end) > 0
      or
      sum(case when g.source = 'post' then 1 else 0 end) > 0
    )
  )
于 2012-12-09T23:00:56.030 回答
1
select id
from
(
    select distinct
    id,
    (
        select
        count(*) from
        song_genre b
        where a.id = b.song_id
        and b.source = 'artist'
    ) as artist,
    (
        select
        count(*) from
        song_genre b
        where a.id = b.song_id
        and b.source = 'blog'
    ) as blog,
    (
        select
        count(*) from
        song_genre b
        where a.id = b.song_id
        and b.source = 'post'
    ) as post,
    (
        select
        count(*) from
        song_genre b
        where a.id = b.song_id
        and b.source = 'tag'
    ) as tag
    from songs A
) AA
where
(AA.artist > 0 AND AA.blog > 0)
OR
(AA.artist > 0 AND AA.post > 0)
OR
(AA.tag > 0)
于 2012-12-09T21:11:13.653 回答