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)