SQL Server FOR EACH 루프
다음 SQL 쿼리가 있습니다.
DECLARE @MyVar datetime = '1/1/2010'
SELECT @MyVar
이것은 자연스럽게 '1/1/2010'을 반환합니다.
내가하고 싶은 것은 날짜 목록이 있습니다.
1/1/2010
2/1/2010
3/1/2010
4/1/2010
5/1/2010
그런 다음 숫자를 통해 각각을 위해 SQL 쿼리를 실행하고 싶습니다.
(의사 코드) :
List = 1/1/2010,2/1/2010,3/1/2010,4/1/2010,5/1/2010
For each x in List
do
DECLARE @MyVar datetime = x
SELECT @MyVar
따라서 다음과 같이 반환됩니다.
2010 년 1 월 1 일 2010 년 2 월 1 일 2010 년 3 월 1 일 2010 년 4 월 1 일 2010 년 5 월 1 일
여러 결과 집합이 아닌 하나의 결과 집합으로 데이터를 반환하기를 원하므로 쿼리 끝에 일종의 통합을 사용해야 할 수 있으므로 루프의 각 반복이 다음으로 통합됩니다.
편집하다
'to date'매개 변수를 허용하는 큰 쿼리가 있습니다. 24 번 실행해야합니다. 매번 제공 할 수 있어야하는 특정 to date (이 날짜는 동적 일 것입니다)를 사용하여 실행해야합니다. 다시 돌아와서 추가 열을 추가해야하는 것처럼 통합 모두를 결합하여 내 쿼리를 24 번 반복하면 시간이 많이 걸립니다.
SQL은 주로 집합 지향 언어입니다. 일반적으로 루프를 사용하는 것은 좋지 않습니다.
이 경우 재귀 CTE를 사용하여 비슷한 결과를 얻을 수 있습니다.
with cte as
(select 1 i union all
select i+1 i from cte where i < 5)
select dateadd(d, i-1, '2010-01-01') from cte
다음은 테이블 변수가있는 옵션입니다.
DECLARE @MyVar TABLE(Val DATETIME)
DECLARE @I INT, @StartDate DATETIME
SET @I = 1
SET @StartDate = '20100101'
WHILE @I <= 5
BEGIN
INSERT INTO @MyVar(Val)
VALUES(@StartDate)
SET @StartDate = DATEADD(DAY,1,@StartDate)
SET @I = @I + 1
END
SELECT *
FROM @MyVar
임시 테이블에서도 똑같이 할 수 있습니다.
CREATE TABLE #MyVar(Val DATETIME)
DECLARE @I INT, @StartDate DATETIME
SET @I = 1
SET @StartDate = '20100101'
WHILE @I <= 5
BEGIN
INSERT INTO #MyVar(Val)
VALUES(@StartDate)
SET @StartDate = DATEADD(DAY,1,@StartDate)
SET @I = @I + 1
END
SELECT *
FROM #MyVar
@JohnFx가 말했듯이 주요 목표가 무엇인지 알려 주셔야합니다. 이것은 아마도 다른 (보다 효율적인) 방법으로 수행 될 수 있습니다.
다음과 같이 변수 테이블을 사용할 수 있습니다.
declare @num int
set @num = 1
declare @results table ( val int )
while (@num < 6)
begin
insert into @results ( val ) values ( @num )
set @num = @num + 1
end
select val from @results
이러한 종류 는 결과 로 수행 하려는 작업 에 따라 다릅니다 . 숫자 바로 뒤에있는 경우 집합 기반 옵션은 모든 종류의 항목에 편리하게 사용할 수있는 숫자 테이블 입니다.
MSSQL 2005+의 경우 재귀 CTE를 사용하여 숫자 테이블을 인라인으로 생성 할 수 있습니다.
;WITH Numbers (N) AS (
SELECT 1 UNION ALL
SELECT 1 + N FROM Numbers WHERE N < 500
)
SELECT N FROM Numbers
OPTION (MAXRECURSION 500)
declare @counter as int
set @counter = 0
declare @date as varchar(50)
set @date = cast(1+@counter as varchar)+'/01/2013'
while(@counter < 12)
begin
select cast(1+@counter as varchar)+'/01/2013' as date
set @counter = @counter + 1
end
물론 오래된 질문입니다. 하지만 루프, CTE, 테이블 변수 등이 필요없는 간단한 솔루션이 있습니다.
DECLARE @MyVar datetime = '1/1/2010'
SELECT @MyVar
SELECT DATEADD (DD,NUMBER,@MyVar)
FROM master.dbo.spt_values
WHERE TYPE='P' AND NUMBER BETWEEN 0 AND 4
ORDER BY NUMBER
Note : spt_values
is a Mircrosoft's undocumented table. It has numbers for every type. Its not suggestible to use as it can be removed in any new versions of sql server without prior information, since it is undocumented. But we can use it as quick workaround in some scenario's like above.
[CREATE PROCEDURE [rat].[GetYear]
AS
BEGIN
-- variable for storing start date
Declare @StartYear as int
-- Variable for the End date
Declare @EndYear as int
-- Setting the value in strat Date
select @StartYear = Value from rat.Configuration where Name = 'REPORT_START_YEAR';
-- Setting the End date
select @EndYear = Value from rat.Configuration where Name = 'REPORT_END_YEAR';
-- Creating Tem table
with [Years] as
(
--Selecting the Year
select @StartYear [Year]
--doing Union
union all
-- doing the loop in Years table
select Year+1 Year from [Years] where Year < @EndYear
)
--Selecting the Year table
selec]
ReferenceURL : https://stackoverflow.com/questions/10300414/sql-server-for-each-loop
'Program Tip' 카테고리의 다른 글
자바 스크립트에서 객체 프로토 타입에 액세스하는 방법은 무엇입니까? (0) | 2020.12.15 |
---|---|
Fortran이 과학 컴퓨팅에 사용되는 이유는 무엇입니까? (0) | 2020.12.15 |
MySQL 오류 1264 : 열의 범위 값을 벗어남 (0) | 2020.12.15 |
C에서 "적어도"int 크기를 어떻게 요청합니까? (0) | 2020.12.15 |
Python / psycopg2 WHERE IN 문 (0) | 2020.12.15 |