[sql] 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



답변

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)


답변

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)


답변

TSQL 쿼리에 대한 동적 csv 목록을 처리하는 방법에는 두 가지가 있습니다.

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) 가능한 세 번째 옵션은 테이블 변수입니다. 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)


답변

다음과 같은 기능을 사용하십시오.

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 레코드 테이블에서 두 번째 버전은 약 절반의 시간이 걸렸습니다 …

건배


답변

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

긴 목록 또는 프로덕션 시스템의 경우 (8000+ 항목 목록을 사용하여 테스트 한) 간단한 IN연산자 보다 훨씬 느릴 수 someColumnName in (1,2,3,4)있으므로이 방법을 사용하지 않는 것이 좋습니다.


답변

아니요, 그러한 유형은 없습니다. 그러나 몇 가지 선택이 있습니다.

  • 동적으로 생성 된 쿼리 (sp_executesql)
  • 임시 테이블
  • 테이블 타입 변수 (리스트에 가장 가까운 것)
  • XML 문자열을 생성 한 다음 XML 함수를 사용하여 테이블로 변환하십시오 (시작할 XML이없는 경우에는 실제로 어색하고 원형입니다)

이것들 중 어느 것도 정말로 우아하지는 않지만, 그것이 최고입니다.


답변

@LukeH가 약간 개선되었으므로 “INSERT INTO”를 반복 할 필요가 없습니다 : @ realPT ‘s answer-SELECT를 가질 필요가 없습니다 :

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

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