1

最終的には、それぞれ「曲」が 1 つしかない「アルバム」レコードを含む「インポート」レコードのリストが必要です。

これは私が今使っているものです:

select i.id, i.created_at 
from imports i 
where i.id in (
    select a.import_id 
    from albums a inner join songs s on a.id = s.album_id
    group by a.id having 1 = count(s.id)
);

ネストされた select (join を使用) は非常に高速ですが、外部の "in" 句は非常に遅いです。

クエリ全体を単一の (ネストなしの) 結合にしようとしましたが、group/having 句で問題が発生しました。私ができる最善のことは、重複を含む「インポート」レコードのリストでしたが、これは受け入れられません。

このクエリを構成するよりエレガントな方法はありますか?

4

5 に答える 5

8

どう?

SELECT i.id,
       i.created_at
FROM   imports i
       INNER JOIN (SELECT   a.import_id
                   FROM     albums a
                            INNER JOIN songs s
                              ON a.id = s.album_id
                   GROUP BY a.id
                   HAVING   Count(* ) = 1) AS TEMP
         ON i.id = TEMP.import_id; 

ほとんどのデータベースシステムでは、JOINはWHERE...INを実行するよりも速く失われます。

于 2009-02-23T20:44:04.440 に答える
4
SELECT i.id, i.created_at, COUNT(s.album_id)
FROM imports AS i
    INNER JOIN albums AS a
        ON i.id = a.import_id
    INNER JOIN songs AS s
        ON a.id = s.album_id
GROUP BY i.id, i.created_at
HAVING COUNT(s.album_id) = 1

COUNT(リスト自体にを含める必要はない場合がありSELECTます。SQLServerはそれを必要としませんが、別のRDBMSが含まれる可能性があります。)

于 2009-02-23T20:45:17.293 に答える
2

未テスト:

select
    i.id, i.created_at
from
    imports i
where
    exists (select *
       from
           albums a
           join
           songs s on a.id = s.album_id
       where
           a.import_id = i.id
       group by
           a.id
       having
           count(*) = 1)

また

select
    i.id, i.created_at
from
    imports i
where
    exists (select *
       from
           albums a
           join
           songs s on a.id = s.album_id
       group by
           a.import_id, a.id
       having
           count(*) = 1 AND a.import_id = i.id)
于 2009-02-23T20:27:05.573 に答える
1

提案された3つのテクニックはすべて、WHEREINよりも高速である必要があります。

  1. 関連するサブクエリ(gbn)とともに存在します
  2. 内部結合されたサブクエリ(achinda99)
  3. 3つのテーブルすべての内部結合(ルーク)

(すべてが機能するはずです...なので、すべて+1します。いずれかが機能しない場合はお知らせください!)

どちらが実際に最速であるかは、データと実行プランによって異なります。しかし、SQLで同じことを表現するためのさまざまな方法の興味深い例。

于 2009-02-23T21:06:34.230 に答える
1

クエリ全体を単一の (ネストなしの) 結合にしようとしましたが、group/having 句で問題が発生しました。

SQL Server バージョン 2005/2008 を使用している場合は、CTE (Common Table Expression) を使用してサブクエリを結合できます。

私の知る限り、CTE は単純に、1 つのselectステートメントで 1 つだけ機能する仮想ビューのように機能する式です。したがって、次のことが可能になります。私は通常、CTE を使用してクエリのパフォーマンスも向上させています。

with AlbumSongs as (
    select  a.import_id 
    from    albums a inner join songs s on a.id = s.album_id
    group by a.id 
    having 1 = count(s.id)
)
select  i.id, i.created_at 
from    imports i 
        inner join AlbumSongs A on A.import_id = i.import_id
于 2009-02-23T21:15:40.403 に答える