3

列がPKであり、一意性制約であるAccountsテーブルがあるとします。IDTaxID+AccountNumber

select * from Accounts where ID in (100, 101)

ここで、自然キーを使用して同様のクエリを実行します。

select * from Accounts 
where {TaxID, AccountNumber} in 
  ({"0123456", "2000897"}, {"0125556", "2000866"})

したがって、これにはタプルが含まれ、かなり正当に見えます。ANSI SQLでなんとか表現することはできますか?たぶん、いくつかの特定のSQL拡張で?そうでない場合は、なぜ(推測に感謝します)?

4

5 に答える 5

3

T-SQLを使用している場合、仮想クエリに少し似ているオプションは、次のようなテーブルリテラルを使用することです。

select * 
from Accounts a
inner join (values('0123456', '2000897'),('0125556', '2000866')) 
    as v(TaxID, AccountNumber) 
    on a.TaxID = v.TaxID and a.AccountNumber = v.AccountNumber

vここでは、フィールドTaxIDとを含むという名前のテーブルリテラルを作成しますAccountNumber。これで、2つのフィールドでテーブルリテラルを結合して、目的の結果を得ることができます。注意点の1つは、テーブルリテラルには1000行しか含めることができないということです。このページで、テーブルリテラルのT-SQLサポートについて詳しく読むことができます。

編集:このページは、この構成がPostgreSQLでも機能することを示しています。

于 2012-01-18T23:11:44.253 に答える
3

これらは両方とも有効なISO/ANSI完全SQL-92構文です。

SELECT a.* 
FROM Accounts a
  INNER JOIN
    ( VALUES('0123456', '2000897'), ('0125556', '2000866')
    ) AS v(TaxID, AccountNumber) 
  ON (a.TaxID, a.AccountNumber) = (v.TaxID, v.AccountNumber)

SELECT * 
FROM Accounts a
WHERE (a.TaxID, a.AccountNumber) IN 
    ( VALUES ('0123456', '2000897'), ('0125556', '2000866') )

しかし、どちらも現在のDBMSでは機能しないと思います。


これは、完全なSQL-92構文でも有効です(SQL-Server 2008では、次の理由により機能しませんNATURAL JOIN)。

SELECT a.* 
FROM Accounts a
  NATURAL JOIN
    ( VALUES('0123456', '2000897'), ('0125556', '2000866')
    ) AS v(TaxID, AccountNumber) 

これも有効なSQLです(92仕様以降かどうかはわかりません)-そしてあなたが持っているものです(ただし、中括弧ではなく括弧を使用します)。
MySQL、Postgres、DB2でサポートされています(SQL Serverではサポートされていません)。

SELECT a.* 
FROM Accounts a
WHERE (TaxID, AccountNumber) IN
    ( ('0123456', '2000897'), ('0125556', '2000866') )
  ;

DBA.SEにも同様の質問がありますが、これを定式化する他のさまざまな方法が
あります。2つの列がセット内のどこにあるかを選択することです。

于 2012-01-19T00:00:15.997 に答える
2

これを解釈する方法に注意してください。サメの答えは機能しますが、戻ります

TaxID        AccountNumber
1234         8765
1234         7654
2345         8765
2345         7654

これはあなたが望むものではないかもしれません...たとえば、税ID 1234のアカウント番号8765と税ID2345の7654だけが必要な場合は、次のようなWHERE句が必要になります。

WHERE (taxId'1234' and accountnumber='8765') OR 
      (taxid='2345' and accountNumber='7654')
于 2012-01-18T22:57:27.607 に答える
2

大まかな方法​​は、2つの値を連結することです。

例えば

SELECT *
FROM Accounts
WHERE CAST(TaxID AS VARCHAR(10)) + '-' + CAST(AccountNumber AS VARCHAR(10)) 
IN ('0123456-2000897', '......', ....)

ただし、たとえばSQL Serverでは、これはインデックスを使用できません。

両方の値を1に結合する計算列を追加して、それに一致させることができます。

SELECT * FROM Accounts WHERE MyComputedColumn IN ('0123456-2000897', ....)


または、次のことができます。

SELECT a.*
FROM Accounts a
    JOIN 
    (
        SELECT '0123456' AS TaxID, '2000897' AS AccountNumber
        UNION ALL
        SELECT '0125556', '2000866'
    ) x ON a.TaxID = x.TaxID AND a.AccountNumber = x.Number
于 2012-01-18T23:00:45.253 に答える
1

Oracle SQLでは、元の投稿の括弧「{}」を括弧で置き換えることができます(2番目の例)。ANSII標準ではないかもしれませんが、それに近く、正常に動作します。

値を連結することはお勧めしません。一般的でない区切り文字を使用しても、自由に入力したテキスト値と誤って一致するという小さなリスクが常にあります。習慣をつけないのが一番です。

于 2013-10-17T18:46:15.890 に答える