it-swarm-ja.tech

IN演算子で使用する変数を定義する(T-SQL)

IN演算子を使用するTransact-SQLクエリがあります。このようなもの:

select * from myTable where myColumn in (1,2,3,4)

リスト全体を保持する変数を定義する方法はありますか?(1,2,3,4)どのように定義すればよいですか?

declare @myList {data type}
set @myList = (1,2,3,4)
select * from myTable where myColumn in @myList
119
Marcos Crispino
DECLARE @MyList TABLE (Value INT)
INSERT INTO @MyList VALUES (1)
INSERT INTO @MyList VALUES (2)
INSERT INTO @MyList VALUES (3)
INSERT INTO @MyList VALUES (4)

SELECT *
FROM MyTable
WHERE MyColumn IN (SELECT Value FROM @MyList)
100
LukeH
DECLARE @mylist TABLE (Id int)
INSERT INTO @mylist
SELECT id FROM (VALUES (1),(2),(3),(4),(5)) AS tbl(id)

SELECT * FROM Mytable WHERE theColumn IN (select id from @mylist)
38
realPT

TSQLクエリの動的csvリストに取り組むには、2つの方法があります。

1)内部選択を使用する

SELECT * FROM myTable WHERE myColumn in (SELECT id FROM myIdTable WHERE id > 10)

2)動的に連結されたTSQLの使用

DECLARE @sql varchar(max)  
declare @list varchar(256)  
select @list = '1,2,3'  
SELECT @sql = 'SELECT * FROM myTable WHERE myColumn in (' + @list + ')'

exec sp_executeSQL @sql

3)考えられる3番目のオプションはテーブル変数です。 SQl Server 2005を使用している場合、テーブル変数を使用できます。 Sql Server 2008の場合、テーブル変数全体をパラメータとしてストアドプロシージャに渡し、IN句の結合または副選択として使用することもできます。

DECLARE @list TABLE (Id INT)

INSERT INTO @list(Id)
SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4


SELECT
    * 
FROM 
    myTable
    JOIN @list l ON myTable.myColumn = l.Id

SELECT
    * 
FROM 
    myTable
WHERE
    myColumn IN (SELECT Id FROM @list)
8
Black Squirrel

次のような関数を使用します。

CREATE function [dbo].[list_to_table] (@list varchar(4000))
returns @tab table (item varchar(100))
begin

if CHARINDEX(',',@list) = 0 or CHARINDEX(',',@list) is null
begin
    insert into @tab (item) values (@list);
    return;
end


declare @c_pos int;
declare @n_pos int;
declare @l_pos int;

set @c_pos = 0;
set @n_pos = CHARINDEX(',',@list,@c_pos);

while @n_pos > 0
begin
    insert into @tab (item) values (SUBSTRING(@list,@c_pos+1,@n_pos - @c_pos-1));
    set @c_pos = @n_pos;
    set @l_pos = @n_pos;
    set @n_pos = CHARINDEX(',',@list,@c_pos+1);
end;

insert into @tab (item) values (SUBSTRING(@list,@l_pos+1,4000));

return;
end;

Likeを使用する代わりに、関数によって返されるテーブルとの内部結合を作成します。

select * from table_1 where id in ('a','b','c')

になる

select * from table_1 a inner join [dbo].[list_to_table] ('a,b,c') b on (a.id = b.item)

インデックスなしの1Mレコードテーブルでは、2番目のバージョンの約半分の時間がかかりました...

乾杯

8
allaphor
DECLARE @myList TABLE (Id BIGINT) INSERT INTO @myList(Id) VALUES (1),(2),(3),(4);
select * from myTable where myColumn in(select Id from @myList)

長いリストまたは実稼働システムでは、someColumnName in (1,2,3,4)(8000以上のアイテムリストを使用してテスト済み)のような単純なINoperatorよりもはるかに低速になる可能性があるため、この方法の使用は推奨されません。

5
Vova

いいえ、そのようなタイプはありません。しかし、いくつかの選択肢があります。

  • 動的に生成されたクエリ(sp_executesql)
  • 一時テーブル
  • テーブル型変数(リストに最も近いもの)
  • XML文字列を作成し、それをXML関数を使用してテーブルに変換します(最初にXMLがなければ、本当に厄介で回り道です)

これらのどれも本当にエレガントではありませんが、それは最高です。

3
Vilx-

@LukeHのわずかな改善、「INSERT INTO」を繰り返す必要はありません:@realPTの答え-SELECTを持つ必要はありません:

DECLARE @MyList TABLE (Value INT) 
INSERT INTO @MyList VALUES (1),(2),(3),(4)

SELECT * FROM MyTable
WHERE MyColumn IN (SELECT Value FROM @MyList)
2
user5292841

私はこれが今では古いことを知っていますが、TSQL => 2016、STRING_SPLITを使用できます:

DECLARE @InList varchar(255) = 'This;Is;My;List';

WITH InList (Item) AS (
    SELECT value FROM STRING_SPLIT(@InList, ';')
)

SELECT * 
FROM [Table]
WHERE [Item] IN (SELECT Tag FROM InList)
2
Nathan Evans

SQL2017以降では、 STRING_SPLIT を使用してこれを実行できます。

declare @myList nvarchar(MAX)
set @myList = '1,2,3,4'
select * from myTable where myColumn in (select value from STRING_SPLIT(@myList,','))
2
Max Favilli

2番目のテーブルを使用せずにこれを実行する場合は、CASTを使用してLIKE比較を実行できます。

DECLARE @myList varchar(15)
SET @myList = ',1,2,3,4,'

SELECT *
FROM myTable
WHERE @myList LIKE '%,' + CAST(myColumn AS varchar(15)) + ',%'

比較するフィールドがすでに文字列である場合、CASTする必要はありません。

列の一致とコンマで囲まれた各一意の値の両方を囲むと、完全に一致するようになります。そうでない場合、「、4,2,15、」を含むリストで値1が見つかります

2
Michael Reyes

これまで誰も言及していなかったように、SQL Server 2016以降では、json配列と OPENJSON (Transact-SQL) を使用することもできます。

declare @filter nvarchar(max) = '[1,2]'

select *
from dbo.Test as t
where
    exists (select * from openjson(@filter) as tt where tt.[value] = t.id)

でテストできますsql fiddle demo

Jsonでより複雑なケースを簡単にカバーすることもできます- SQL変数でWHERE IN句を使用してSQLで値と範囲のリストを検索しますか? を参照してください

1
Roman Pekar

文字列を宣言してから、そのSQL文字列を実行する必要があると思います。

Sp_ExecuteSQLをご覧ください

0
BIDeveloper
DECLARE @StatusList varchar(MAX);
SET @StatusList='1,2,3,4';
DECLARE @Status SYS_INTEGERS;
INSERT INTO  @Status 
SELECT Value 
FROM dbo.SYS_SPLITTOINTEGERS_FN(@StatusList, ',');
SELECT Value From @Status;