programing

각 루프에 대한 SQL Server

telecom 2023. 7. 9. 09:48
반응형

각 루프에 대한 SQL Server

다음 SQL 쿼리가 있습니다.

DECLARE @MyVar datetime = '1/1/2010'    
SELECT @MyVar

그러면 자연스럽게 '2010년 1월 1일'이 반환됩니다.

제가 하고 싶은 것은 날짜 목록을 만드는 것은 다음과 같습니다.

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

그래서 이것은 돌아올 것입니다:-

1/1/2010 2/1/2010 3/1/2010 4/1/2010 5/1/2010

여러 결과 집합이 아닌 하나의 결과 집합으로 데이터를 반환하기를 원하므로 쿼리 끝에 일종의 결합을 사용해야 할 수 있으므로 루프의 각 반복이 다음으로 결합됩니다.

편집을

'현재 날짜' 매개 변수를 수락하는 대규모 쿼리가 있습니다. 특정 날짜를 입력할 수 있는 특정 날짜를 사용하여 매번 24번 실행해야 합니다(이 날짜는 동적일 것입니다). 다시 돌아와서 추가 열을 추가해야 하는 것처럼 유니온 모두가 참여한 상태에서 쿼리가 24번 반복되는 것을 피하고 싶습니다.

SQL은 기본적으로 집합 지향적인 언어입니다. 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

물론 오래된 질문입니다.하지만 Looping, CTE, Table 변수 등이 필요 없는 간단한 솔루션이 있습니다.

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

참고: spt_values마이크로소프트의 문서화되지 않은 표입니다.모든 유형에 대한 숫자가 있습니다.문서화되지 않았기 때문에 사전 정보 없이 새 버전의 SQL 서버에서 제거할 수 있으므로 사용할 수 없습니다.그러나 위와 같은 시나리오에서는 빠른 해결 방법으로 사용할 수 있습니다.

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

언급URL : https://stackoverflow.com/questions/10300414/sql-server-for-each-loop

반응형