37

foo複合主キーを持つテーブルが与えられた場合、次(a,b)のようなクエリを作成するための正当な構文はありますか?

SELECT ... FROM foo WHERE a,b IN (SELECT ...many tuples of a/b values...);
UPDATE foo SET ... WHERE a,b IN (SELECT ...many tuples of a/b values...);

これが不可能で、スキーマを変更できない場合、上記と同等の機能をどのように実行できますか?

また、これらのエイリアスの検索ヒットに対して、「複合主キー」、「副選択」、「副選択」、および「副クエリ」という用語をここに配置します。

編集:標準SQLの回答だけでなく、PostgreSQLとSQLite3で動作する回答にも興味があります。

4

9 に答える 9

27
sqlite> create table foo (a,b,c);
sqlite> create table bar (x,y);
sqlite> select * from foo where exists (select 1 from bar where foo.a = bar.x and foo.b = bar.y);

をに置き換えselect 1 from barますselect ... many tuples of a/b values ...

または、の一時テーブルを作成して、 .select ... many tuples of a/b values ...の代わりに使用しbarます。

于 2011-01-07T04:31:32.383 に答える
24

あなたの構文は標準SQLに非常に近いです!

以下は、有効なFULL SQL-92です(Mimer SQL-92 Validatorによって確認されています) 。

SELECT * 
  FROM foo 
  WHERE (a, b) IN (
                   SELECT a, b 
                      FROM bar
                  );

もちろん、すべてのSQL製品が完全なSQL-92をサポートしているわけではありません(残念です!)この構文がMicrosoft SQL Serverでサポートされていることを知りたい場合は、ここで投票できます。

より広くサポートされている(たとえば、Microsoft SQL ServerやOracleによって)さらにSQL-92構造は、次のとおりですINTERSECT

SELECT a, b
  FROM Foo
INTERSECT
SELECT a, b
  FROM Bar;

これらの構成NULLは、ここでの他の提案のいくつかとは異なり、値を適切に処理することに注意してください。たとえばEXISTS (<equality predicates>)、連結値などを使用する提案です。

于 2011-01-07T11:27:52.383 に答える
11

あなたはほんの少しの間違いをしました。a、bをかっこで囲む必要があります。

SELECT ... FROM foo WHERE (a,b) IN (SELECT f,d FROM ...);

それはうまくいきます!

于 2012-08-01T13:04:07.460 に答える
4

提案したIN構文は有効なSQLではありません。EXISTSを使用するソリューションは、すべての合理的に準拠するSQLRDBMSで機能するはずです。

 UPDATE foo SET x = y WHERE EXISTS
    (SELECT * FROM bar WHERE bar.c1 = foo.c1 AND bar.c2 = foo.c2)

多くの場合、これは特にパフォーマンスが高くないことに注意してください。

于 2011-01-07T04:52:37.880 に答える
3
    SELECT ...
      FROM foo
INNER JOIN (SELECT ...many tuples of a/b values...) AS results
        ON results.a = foo.a
       AND results.b = foo.b

それはあなたが探しているものですか?

于 2011-01-07T04:20:01.080 に答える
1

連結すると、これはPostgreSQLで機能します。

SELECT a,b FROM foo WHERE a||b IN (SELECT a||b FROM bar WHERE condition);

UPDATE foo SET x=y WHERE a||b IN (SELECT a||b FROM bar WHERE condition);
于 2011-01-07T10:24:23.500 に答える
0

JOINSINTERSECTS代わりとしては問題なく機能しますが、たとえば、両方のテーブルのが複合である場所にまだ存在しない場所に行を挿入するなど、INの代わりとしてはそれほど明白ではありません。NOT INTableATableBTableBPK

現在、SQL Serverで上記の連結方法を使用していますが、これはあまり洗練されたソリューションではありません。

于 2011-04-05T12:45:56.723 に答える
0

テーブルにすでに存在する値のタプルを必要としないソリューションが必要な場合は、リスト内の関連するテーブル値とアイテムを連結してから、「IN」コマンドを使用できます。

postgresでは、これは次のようになります。

SELECT * FROM foo WHERE a || '_' || b in ('Hi_there', 'Me_here', 'Test_test');

SQLを使用していると、次のようになります。

SELECT * FROM foo WHERE CONCAT(a, "_", b) in ('Hi_there', 'Me_here', 'Test_test');

于 2012-11-09T05:29:46.087 に答える
0

Firebirdは、次の連結式を使用します。

SELECT a、b FROM foo WHERE a || b IN(SELECT a || b FROM bar WHERE条件);

于 2013-10-14T07:38:16.923 に答える