0

曲とジャンルをつなぐテーブルに参加しました。このテーブルには、ジャンルが見つかった場所を識別するために使用される「ソース」列があります。ジャンルは、ブログ、アーティスト、タグ、投稿から見つかります。

それで、

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

私が構築したいのは、すでにgenre_idがある場合、次のように機能する曲のSELECTクエリです。

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'

たくさんの結合を行うことでそれを行うつもりでしたが、私はそれをあまりうまくやっていないと確信しています。

Postgres9.1の使用。

4

2 に答える 2

3

kgu87のクエリは正しいですが、副選択に対して多数のカウントがある比較的高価なプランを生成する可能性があります。これらのカウントはすべてcase、ソースにsがあり、が。のジャンルテーブルを1回パスするだけで累積できます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 に答える