2

特定の制約に対してテーブル B に同等のアイテムが存在するテーブル A からアイテムを選択しようとしています。テーブル A には ID ごとに 1 つの行がありますが、テーブル A の行ごとに多くの行があります。

select distinct A.id 
from A inner join B on B.a_id = A.id 
where B.x >= 5 and B.x <= 10;

テーブル A の行ごとに 1 つの行のみを取得するために使用できる SQL 結合句があるかどうか疑問に思います。

私が理解しているように、クエリは制約を見つけ、内部結合を実行してから、これに対して個別に実行します。これが正しく、データベースに A とは異なる行のみを取得するように指示するより良い方法がある場合は、知りたいです。クエリのセマンティクスの制約内で、クエリを解釈して実行する方法はたくさんあると確信しています。explain出力を理解しているとは言えません。

これを簡単にする方法はありますか?それが違いを生むなら、私はSQLiteに制約されています。

編集

制約句には、クエリ時に定義された 2 つの制約があり、これを追加しました。私は質問をできるだけ単純にしようとしましたが、コメントに応じて完全を期すために余分な節を追加しました.

4

2 に答える 2

3

クエリを記述する別の方法を次に示します。

select A.id
from A
where A.id in (select B.a_id from B where B.x > 5)

パフォーマンスが向上するとは思いませんが、外側の「独特」はなくなります。

MySQL で使用する別のバージョンがあります。

select A.id
from A
where exists (select 1 from B where b.x > 5 and b.a_id = a.id limit 1)

これは、クエリがインデックス ルックアップを使用して最初の一致で停止できるため、より効率的である可能性があります。これは、B に (a_id, x) のインデックスがある場合に特に当てはまります。

于 2012-09-10T19:24:17.703 に答える
1

2 つのテーブルの間に(適切に適用された) がある場合FOREIGN KEY、テーブルを削除することで (わずかに) 効率が向上しますA

SELECT DISTINCT a_id AS id
FROM B 
WHERE x >= 5 and x <= 10 ;

インデックス(a_id, x)は適切に見えますが、効率はさまざまなパラメーター (条件に一致する ID の割合、x>5同じ ID を持つ行の数など) によって異なります。

このクエリも試してみます(上記のインデックスを追加した後):

SELECT a_id AS id
FROM B 
GROUP BY a_id
HAVING MAX(x) >= 5 
   AND MIN(x) <= 10 ;

これは、次のデータも必要な場合に機能しAます。

SELECT A.* 
FROM A
  JOIN 
    ( SELECT a_id
      FROM B 
      GROUP BY a_id
      HAVING MAX(x) >= 5 
         AND MIN(x) <= 10  
    ) AS b
  ON b.a_id = a.id ;
于 2012-09-10T20:18:29.587 に答える