Group_idフィールドとgroup_typeフィールドを含むテーブルがあり、タプル(group id、タプルのリストからのグループタイプ)。たとえば、次のようなことができるようにしたいと思います。
SELECT *
FROM mytable
WHERE (group_id, group_type) IN (("1234-567", 2), ("4321-765", 3), ("1111-222", 5))
非常によく似た質問が sql in節のタプルを使用して で既に尋ねられていますが、そこで提案されているソリューションは、タプルリストが別のテーブルからフェッチされることを前提としています。私の場合、これは機能しません。タプル値がハードコーディングされています。
1つの解決策は、文字列の連結を使用することです。
SELECT *
FROM mytable
WHERE group_id + STR(group_type, 1) IN ("1234-5672", "4321-7653", "1111-2225")
しかし問題は、テーブルが非常に大きく、各レコードに対して文字列の連結と変換を行うと非常に高価になることです。
なにか提案を?
ORステートメントを作成しないのはなぜですか?
SELECT *
FROM mytable
WHERE (group_id = '1234-567' and group_type = 2)
OR (group_id = '4321-765' and group_type = 3)
OR (group_id = '1111-222' and group_type = 5)
確かに、それはあなたの概念の例のように見栄えが良くてきれいではありませんが、仕事をします(そしてタプルを持つIN
が存在した場合、ほとんどの場合カバーとまったく同じ方法でそれを実装します。
非常にマイナーなTweak(二重引用符を単一で置き換え、VALUES
キーワードを追加)が与えられた場合、提案された構文は有効な標準SQL-92構文です。
SELECT *
FROM mytable
WHERE (group_id, group_type) IN (
VALUES ('1234-567', 2),
('4321-765', 3),
('1111-222', 5)
);
悲しいことに、MSFTはそれをSQL Serverに追加しておらず、 「計画外の」機能と考えてください です。
FWIW PostgreSQLおよびSqliteは、この構文をサポートするSQL製品の例です。
SQL Server 2008では、次のようにできます。
select *
from mytable as T
where exists (select *
from (values ('1234-567', 2),
('4321-765', 3),
('1111-222', 5)) as V(group_id, group_type)
where T.group_id = V.group_id and
T.group_type = V.group_type
)
共通テーブル式を使用して、これらのタプルが別のテーブルにあるふりをすることができます。
;WITH Tuples as (
select '1234-567' as group_id, 2 as group_type union all
select '4321-765', 3 union all
select '1111-222', 5
)
SELECT * /* TODO - Pick appropriate columns */
from mytable m where exists (
select * from Tuples t
where m.group_id = t.group_id and m.group_type = t.group_type)
そのソリューションを使用すると、これは機能するはずです:
SELECT *
FROM mytable m
WHERE EXISTS (
SELECT * FROM (
SELECT "1234-567" group_id, 2 group_type UNION ALL
SELECT "4321-765", 3 UNION ALL
SELECT "1111-222", 5) [t]
WHERE m.group_id = t.group_id AND m.group_type = t.group_type)
ところで、おそらく内部テーブルを作成するには [〜#〜] cte [〜#〜] を使用する必要があります。
結合を使用する別のTupleソリューションを次に示します。
SELECT
*
FROM mytable m
JOIN
(
SELECT "1234-567" group_id, 2 group_type
UNION ALL SELECT "4321-765", 3
UNION ALL SELECT "1111-222", 5
) [t]
ON m.group_id = t.group_id
AND m.group_type = t.group_type
同様の問題がありましたが、Tupleコレクションは動的でした-クエリパラメーターでSQL Serverに送信されました。私は次の解決策を思いつきました:
タプルをXMLとして渡します。
DECLARE @tuplesXml xml = '<tuples><Tuple group-id="1234-567" group-type="2"/><Tuple group-id="4321-765" group-type="3"/></tuples>';
XMLノードでフィルター処理するテーブルを内部結合します。
SELECT t.* FROM mytable t
INNER JOIN @tuplesXml.nodes('/tuples/Tuple') AS Tuple(col)
ON Tuple.col.value('./@group-id', 'varchar(255)') = t.group_id
AND Tuple.col.value('./@group-type', 'integer') = t.group_type
質問で説明されているものよりも少し複雑な私の状況ではうまくいくようです。
t.*
の代わりに*
を使用する必要があり、nodes
メソッドから返されるテーブルはエイリアス化する必要があることに注意してください(この場合はTuple(col)
です)。
select * from table_name where 1=1 and (column_a, column_b) in ((28,1),(25,1))