복붙노트

[SQL] 어떻게 두 숫자 사이의 숫자의 범위를 생성하는?

SQL

어떻게 두 숫자 사이의 숫자의 범위를 생성하는?

I는, 예를 들면 1000, 1050와 같이, 사용자로부터 입력 된 두 개의 번호를 갖는다.

어떻게 별도의 행에, SQL 쿼리를 사용하여,이 두 숫자 사이의 번호를 생성합니까? 나는이 원하는 :

 1000
 1001
 1002
 1003
 .
 .
 1050

해결법

  1. ==============================

    1.값 키워드와 비 지속 값을 선택합니다. 그런 다음 사용이 많은 조합을 많이 생성하는 조인 (행 이후 수십만를 만들 확장 할 수 있습니다).

    값 키워드와 비 지속 값을 선택합니다. 그런 다음 사용이 많은 조합을 많이 생성하는 조인 (행 이후 수십만를 만들 확장 할 수 있습니다).

    SELECT ones.n + 10*tens.n + 100*hundreds.n + 1000*thousands.n
    FROM (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) ones(n),
         (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) tens(n),
         (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) hundreds(n),
         (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) thousands(n)
    WHERE ones.n + 10*tens.n + 100*hundreds.n + 1000*thousands.n BETWEEN @userinput1 AND @userinput2
    ORDER BY 1
    

    데모

    쉽게로되지 않는 짧은 대안은 이해하기 :

    WITH x AS (SELECT n FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) v(n))
    SELECT ones.n + 10*tens.n + 100*hundreds.n + 1000*thousands.n
    FROM x ones,     x tens,      x hundreds,       x thousands
    ORDER BY 1
    

    데모

  2. ==============================

    2.대체 솔루션은 재귀 CTE는 다음과 같습니다

    대체 솔루션은 재귀 CTE는 다음과 같습니다

    DECLARE @startnum INT=1000
    DECLARE @endnum INT=1050
    ;
    WITH gen AS (
        SELECT @startnum AS num
        UNION ALL
        SELECT num+1 FROM gen WHERE num+1<=@endnum
    )
    SELECT * FROM gen
    option (maxrecursion 10000)
    
  3. ==============================

    3.

    SELECT DISTINCT n = number 
    FROM master..[spt_values] 
    WHERE number BETWEEN @start AND @end
    

    데모

    다음 숫자가 차이가 있기 때문에이 테이블 2048의 최대를 가지고 있습니다.

    여기 (SQL-서버 2005 이후) 시스템 뷰를 사용하여 약간 더 나은 방법입니다 :

    ;WITH Nums AS
    (
      SELECT n = ROW_NUMBER() OVER (ORDER BY [object_id]) 
      FROM sys.all_objects 
    
    )
    SELECT n FROM Nums 
    WHERE n BETWEEN @start AND @end
    ORDER BY n;
    

    데모

    또는 사용자 정의 a를 번호 테이블을 사용합니다. 아론 버트 랜드에 학점, 나는 전체 기사를 읽고하는 것이 좋습니다 : 루프없이 세트 또는 시퀀스를 생성

  4. ==============================

    4.나는 최근에 바로이 문제를 해결하기 위해이 인라인 테이블 반환 함수를 썼다. 그것은 메모리와 저장 이외의 범위에 제한 아니에요. 읽거나 일반적으로 쓰는 디스크에 대한 필요가 없습니다 그래서 더 테이블에 액세스하지 않습니다. 그것은 매우 큰 범위에 대해서도 매우 빠른 그래서이 반복 될 때마다 기하 급수적으로 값을 조인 추가합니다. 그것은 내 서버에 5 초 천만 레코드를 작성합니다. 또한 음의 값으로 작동합니다.

    나는 최근에 바로이 문제를 해결하기 위해이 인라인 테이블 반환 함수를 썼다. 그것은 메모리와 저장 이외의 범위에 제한 아니에요. 읽거나 일반적으로 쓰는 디스크에 대한 필요가 없습니다 그래서 더 테이블에 액세스하지 않습니다. 그것은 매우 큰 범위에 대해서도 매우 빠른 그래서이 반복 될 때마다 기하 급수적으로 값을 조인 추가합니다. 그것은 내 서버에 5 초 천만 레코드를 작성합니다. 또한 음의 값으로 작동합니다.

    CREATE FUNCTION [dbo].[fn_ConsecutiveNumbers]
    (   
        @start int,
        @end  int
    ) RETURNS TABLE 
    RETURN 
    
    select
        x268435456.X
        | x16777216.X
        | x1048576.X
        | x65536.X
        | x4096.X
        | x256.X
        | x16.X
        | x1.X
        + @start
         X
    from
    (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)) as x1(X)
    join
    (VALUES (0),(16),(32),(48),(64),(80),(96),(112),(128),(144),(160),(176),(192),(208),(224),(240)) as x16(X)
    on x1.X <= @end-@start and x16.X <= @end-@start
    join
    (VALUES (0),(256),(512),(768),(1024),(1280),(1536),(1792),(2048),(2304),(2560),(2816),(3072),(3328),(3584),(3840)) as x256(X)
    on x256.X <= @end-@start
    join
    (VALUES (0),(4096),(8192),(12288),(16384),(20480),(24576),(28672),(32768),(36864),(40960),(45056),(49152),(53248),(57344),(61440)) as x4096(X)
    on x4096.X <= @end-@start
    join
    (VALUES (0),(65536),(131072),(196608),(262144),(327680),(393216),(458752),(524288),(589824),(655360),(720896),(786432),(851968),(917504),(983040)) as x65536(X)
    on x65536.X <= @end-@start
    join
    (VALUES (0),(1048576),(2097152),(3145728),(4194304),(5242880),(6291456),(7340032),(8388608),(9437184),(10485760),(11534336),(12582912),(13631488),(14680064),(15728640)) as x1048576(X)
    on x1048576.X <= @end-@start
    join
    (VALUES (0),(16777216),(33554432),(50331648),(67108864),(83886080),(100663296),(117440512),(134217728),(150994944),(167772160),(184549376),(201326592),(218103808),(234881024),(251658240)) as x16777216(X)
    on x16777216.X <= @end-@start
    join
    (VALUES (0),(268435456),(536870912),(805306368),(1073741824),(1342177280),(1610612736),(1879048192)) as x268435456(X)
    on x268435456.X <= @end-@start
    WHERE @end >=
        x268435456.X
        | isnull(x16777216.X, 0)
        | isnull(x1048576.X, 0)
        | isnull(x65536.X, 0)
        | isnull(x4096.X, 0)
        | isnull(x256.X, 0)
        | isnull(x16.X, 0)
        | isnull(x1.X, 0)
        + @start
    
    GO
    
    SELECT X FROM fn_ConsecutiveNumbers(5, 500);
    

    그것은뿐만 아니라 날짜와 시간 범위에 대해 편리합니다 :

    SELECT DATEADD(day,X, 0) DayX 
    FROM fn_ConsecutiveNumbers(datediff(day,0,'5/8/2015'), datediff(day,0,'5/31/2015'))
    
    SELECT DATEADD(hour,X, 0) HourX 
    FROM fn_ConsecutiveNumbers(datediff(hour,0,'5/8/2015'), datediff(hour,0,'5/8/2015 12:00 PM'));
    

    당신은 크로스 테이블의 값을 기준으로 분할 기록에 조인 적용 사용할 수 있습니다. 그래서 예를 들어 당신이 좋아하는 일을 할 수있는 테이블의 시간 범위에있는 모든 분에 대한 기록을 만들 수 있습니다 :

    select TimeRanges.StartTime,
        TimeRanges.EndTime,
        DATEADD(minute,X, 0) MinuteX
    FROM TimeRanges
    cross apply fn_ConsecutiveNumbers(datediff(hour,0,TimeRanges.StartTime), 
            datediff(hour,0,TimeRanges.EndTime)) ConsecutiveNumbers
    
  5. ==============================

    5.다음과 같이 내가 사용한 가장 좋은 방법은 다음과 같습니다

    다음과 같이 내가 사용한 가장 좋은 방법은 다음과 같습니다

    DECLARE @min bigint, @max bigint
    SELECT @Min=919859000000 ,@Max=919859999999
    
    SELECT TOP (@Max-@Min+1) @Min-1+row_number() over(order by t1.number) as N
    FROM master..spt_values t1 
        CROSS JOIN master..spt_values t2
    

    나는 이것을 사용하여 수백만 개의 레코드를 생성하고 그것을 완벽하게 작동합니다.

  6. ==============================

    6.그것은 나를 위해 작동!

    그것은 나를 위해 작동!

    select top 50 ROW_NUMBER() over(order by a.name) + 1000 as Rcount
    from sys.all_objects a
    
  7. ==============================

    7.가장 좋은 방법은 재귀 CTE를 사용하고 있습니다.

    가장 좋은 방법은 재귀 CTE를 사용하고 있습니다.

    declare @initial as int = 1000;
    declare @final as int =1050;
    
    with cte_n as (
        select @initial as contador
        union all
        select contador+1 from cte_n 
        where contador <@final
    ) select * from cte_n option (maxrecursion 0)
    

    인사.

  8. ==============================

    8.

    declare @start int = 1000
    declare @end    int =1050
    
    ;with numcte  
    AS  
    (  
      SELECT @start [SEQUENCE]  
      UNION all  
      SELECT [SEQUENCE] + 1 FROM numcte WHERE [SEQUENCE] < @end 
    )      
    SELECT * FROM numcte
    
  9. ==============================

    9.당신은 좋은 옵션은 .NET에서 테이블 반환 함수를 작성하는 서버에 어셈블리 CLR을 설치 문제가없는 경우. 그런 식으로 당신은 쉽게 다른 쿼리와 그 결과가 스트리밍되기 때문에 메모리를 낭비하지 않습니다 보너스로 가입하고, 간단한 구문을 사용할 수 있습니다.

    당신은 좋은 옵션은 .NET에서 테이블 반환 함수를 작성하는 서버에 어셈블리 CLR을 설치 문제가없는 경우. 그런 식으로 당신은 쉽게 다른 쿼리와 그 결과가 스트리밍되기 때문에 메모리를 낭비하지 않습니다 보너스로 가입하고, 간단한 구문을 사용할 수 있습니다.

    다음 클래스를 포함하는 프로젝트를 생성합니다 :

    using System;
    using System.Collections;
    using System.Data;
    using System.Data.Sql;
    using System.Data.SqlTypes;
    using Microsoft.SqlServer.Server;
    
    namespace YourNamespace
    {
       public sealed class SequenceGenerator
        {
            [SqlFunction(FillRowMethodName = "FillRow")]
            public static IEnumerable Generate(SqlInt32 start, SqlInt32 end)
            {
                int _start = start.Value;
                int _end = end.Value;
                for (int i = _start; i <= _end; i++)
                    yield return i;
            }
    
            public static void FillRow(Object obj, out int i)
            {
                i = (int)obj;
            }
    
            private SequenceGenerator() { }
        }
    }
    

    서버와 실행에 조립 어딘가에 넣어 :

    USE db;
    CREATE ASSEMBLY SqlUtil FROM 'c:\path\to\assembly.dll'
    WITH permission_set=Safe;
    
    CREATE FUNCTION [Seq](@start int, @end int) 
    RETURNS TABLE(i int)
    AS EXTERNAL NAME [SqlUtil].[YourNamespace.SequenceGenerator].[Generate];
    

    지금 당신은 실행할 수 있습니다 :

    select * from dbo.seq(1, 1000000)
    
  10. ==============================

    10.아무것도 새로운하지만 눈에 쉽게 될 브라이언 프레슬러 솔루션을 재 작성, 누군가 (그냥 미래의 나를 경우에도)에 유용 할 수 있습니다 :

    아무것도 새로운하지만 눈에 쉽게 될 브라이언 프레슬러 솔루션을 재 작성, 누군가 (그냥 미래의 나를 경우에도)에 유용 할 수 있습니다 :

    alter function [dbo].[fn_GenerateNumbers]
    (   
        @start int,
        @end  int
    ) returns table
    return
    
    with 
    b0 as (select n from (values (0),(0x00000001),(0x00000002),(0x00000003),(0x00000004),(0x00000005),(0x00000006),(0x00000007),(0x00000008),(0x00000009),(0x0000000A),(0x0000000B),(0x0000000C),(0x0000000D),(0x0000000E),(0x0000000F)) as b0(n)),
    b1 as (select n from (values (0),(0x00000010),(0x00000020),(0x00000030),(0x00000040),(0x00000050),(0x00000060),(0x00000070),(0x00000080),(0x00000090),(0x000000A0),(0x000000B0),(0x000000C0),(0x000000D0),(0x000000E0),(0x000000F0)) as b1(n)),
    b2 as (select n from (values (0),(0x00000100),(0x00000200),(0x00000300),(0x00000400),(0x00000500),(0x00000600),(0x00000700),(0x00000800),(0x00000900),(0x00000A00),(0x00000B00),(0x00000C00),(0x00000D00),(0x00000E00),(0x00000F00)) as b2(n)),
    b3 as (select n from (values (0),(0x00001000),(0x00002000),(0x00003000),(0x00004000),(0x00005000),(0x00006000),(0x00007000),(0x00008000),(0x00009000),(0x0000A000),(0x0000B000),(0x0000C000),(0x0000D000),(0x0000E000),(0x0000F000)) as b3(n)),
    b4 as (select n from (values (0),(0x00010000),(0x00020000),(0x00030000),(0x00040000),(0x00050000),(0x00060000),(0x00070000),(0x00080000),(0x00090000),(0x000A0000),(0x000B0000),(0x000C0000),(0x000D0000),(0x000E0000),(0x000F0000)) as b4(n)),
    b5 as (select n from (values (0),(0x00100000),(0x00200000),(0x00300000),(0x00400000),(0x00500000),(0x00600000),(0x00700000),(0x00800000),(0x00900000),(0x00A00000),(0x00B00000),(0x00C00000),(0x00D00000),(0x00E00000),(0x00F00000)) as b5(n)),
    b6 as (select n from (values (0),(0x01000000),(0x02000000),(0x03000000),(0x04000000),(0x05000000),(0x06000000),(0x07000000),(0x08000000),(0x09000000),(0x0A000000),(0x0B000000),(0x0C000000),(0x0D000000),(0x0E000000),(0x0F000000)) as b6(n)),
    b7 as (select n from (values (0),(0x10000000),(0x20000000),(0x30000000),(0x40000000),(0x50000000),(0x60000000),(0x70000000)) as b7(n))
    
    select s.n
    from (
        select
              b7.n
            | b6.n
            | b5.n
            | b4.n
            | b3.n
            | b2.n
            | b1.n
            | b0.n
            + @start
             n
        from b0
        join b1 on b0.n <= @end-@start and b1.n <= @end-@start
        join b2 on b2.n <= @end-@start
        join b3 on b3.n <= @end-@start
        join b4 on b4.n <= @end-@start
        join b5 on b5.n <= @end-@start
        join b6 on b6.n <= @end-@start
        join b7 on b7.n <= @end-@start
    ) s
    where @end >= s.n
    
    GO
    
  11. ==============================

    11.나중에 2 년,하지만 난 같은 문제가 있었다 발견했다. 여기에 내가 그것을 해결하는 방법입니다. (파라미터를 포함하도록 수정)

    나중에 2 년,하지만 난 같은 문제가 있었다 발견했다. 여기에 내가 그것을 해결하는 방법입니다. (파라미터를 포함하도록 수정)

    DECLARE @Start INT, @End INT
    SET @Start = 1000
    SET @End = 1050
    
    SELECT  TOP (@End - @Start+1) ROW_NUMBER() OVER (ORDER BY S.[object_id])+(@Start - 1) [Numbers]
    FROM    sys.all_objects S WITH (NOLOCK)
    
  12. ==============================

    12.여기에 몇 가지 아주 최적의 호환 솔루션은 다음과 같습니다 :

    여기에 몇 가지 아주 최적의 호환 솔루션은 다음과 같습니다 :

    USE master;
    
    declare @min as int;    set @min = 1000;
    declare @max as int;    set @max = 1050;    --null returns all
    
    --  Up to 256 - 2 048 rows depending on SQL Server version
    select  isnull(@min,0)+number.number  as  number
    FROM    dbo.spt_values  AS  number
    WHERE   number."type"                   =   'P'     --integers
        and (   @max                            is null     --return all
            or  isnull(@min,0)+number.number    <=  @max    --return up to max
        )
    order by    number
    ;
    
    --  Up to 65 536 - 4 194 303 rows depending on SQL Server version
    select  isnull(@min,0)+value1.number+(value2.number*numberCount.numbers)  as  number
    FROM  dbo.spt_values            AS  value1
      cross join  dbo.spt_values    AS  value2
      cross join (  --get the number of numbers (depends on version)
        select  sum(1)  as  numbers
        from    dbo.spt_values
        where   spt_values."type"   =   'P' --integers
      )                             as  numberCount
    WHERE   value1."type" = 'P'   --integers
        and value2."type" = 'P'   --integers
        and (   @max    is null     --return all
            or  isnull(@min,0)+value1.number+(value2.number*numberCount.numbers)    
                <=  @max            --return up to max
        )
    order by    number
    ;
    
  13. ==============================

    13.slartidan의 대답은 데카르트 제품에 대한 모든 참조를 제거하고 ROW_NUMBER () 대신 (실행 계획 비교)을 사용하여, 현명한 성능을 향상시킬 수 :

    slartidan의 대답은 데카르트 제품에 대한 모든 참조를 제거하고 ROW_NUMBER () 대신 (실행 계획 비교)을 사용하여, 현명한 성능을 향상시킬 수 :

    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM 
    (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x1(x),
    (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x2(x),
    (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x3(x),
    (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x4(x),
    (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x5(x)
    ORDER BY n
    

    CTE를 내부를 감싸고 원하는 번호를 선택하는 where 절을 추가합니다 :

    DECLARE @n1 AS INT = 100;
    DECLARE @n2 AS INT = 40099;
    WITH numbers AS (
        SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM 
        (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x1(x),
        (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x2(x),
        (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x3(x),
        (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x4(x),
        (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x5(x)
    )
    SELECT numbers.n
    FROM numbers
    WHERE n BETWEEN @n1 and @n2
    ORDER BY n
    
  14. ==============================

    14.내가 너무 늦게 사년이야 알지만,이 문제에 대한 또 다른 대안 대답 우연히. 속도 문제는 사전에 필터링되지 않고, 또한 정렬을 방지 할 수있다. 그것은 데카르트의 제품이 실제로 조인의 결과로 계산하는 방식으로 실행하는 조인 순서를 강제하는 것이 가능하다. 점프 - 오프 포인트로 slartidan의 답변을 사용 :

    내가 너무 늦게 사년이야 알지만,이 문제에 대한 또 다른 대안 대답 우연히. 속도 문제는 사전에 필터링되지 않고, 또한 정렬을 방지 할 수있다. 그것은 데카르트의 제품이 실제로 조인의 결과로 계산하는 방식으로 실행하는 조인 순서를 강제하는 것이 가능하다. 점프 - 오프 포인트로 slartidan의 답변을 사용 :

        WITH x AS (SELECT n FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) v(n))
    SELECT ones.n + 10*tens.n + 100*hundreds.n + 1000*thousands.n
    FROM x ones,     x tens,      x hundreds,       x thousands
    ORDER BY 1
    

    우리는 우리가 원하는 범위를 알고 있다면, 우리는 @Upper 및 @Lower 통해 지정할 수 있습니다. (가) REMOTE TOP과 함께 조인 힌트를 결합함으로써, 우리는 우리가 낭비 아무것도 원하는 값의 하위 집합을 계산할 수 있습니다.

    WITH x AS (SELECT n FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) v(n))
    SELECT TOP (1+@Upper-@Lower) @Lower + ones.n + 10*tens.n + 100*hundreds.n + 1000*thousands.n
    FROM x thousands
    INNER REMOTE JOIN x hundreds on 1=1
    INNER REMOTE JOIN x tens on 1=1
    INNER REMOTE JOIN x ones on 1=1
    

    는 옵티마이의 오른쪽에 비교하는 힌트 REMOTE 세력이 먼저 조인. 각 원격으로 가입 지정함으로써 대부분의 최하위 값은 그 자체가 정확하게 의해 위쪽으로 계산한다 조인. 주문 BY로 정렬합니다 WHERE 또는과 필터 필요가 없습니다.

    당신이 범위를 늘리려면 그들이 FROM 절에서 최하위에 가장에서 주문하고, 당신은 너무 오래, 크기 점진적으로 더 높은 순서로 조인 추가를 계속 추가 할 수 있습니다.

    이 SQL Server 2008 또는 이상으로 쿼리 특정합니다.

  15. ==============================

    15.이것은 또한 할 것

    이것은 또한 할 것

    DECLARE @startNum INT = 1000;
    DECLARE @endNum INT = 1050;
    INSERT  INTO dbo.Numbers
            ( Num
            )
            SELECT  CASE WHEN MAX(Num) IS NULL  THEN @startNum
                         ELSE MAX(Num) + 1
                    END AS Num
            FROM    dbo.Numbers
    GO 51
    
  16. ==============================

    16.최고 속도 실행시 쿼리

    최고 속도 실행시 쿼리

    DECLARE @num INT = 1000
    WHILE(@num<1050)
    begin
     INSERT  INTO [dbo].[Codes]
        (   Code
        ) 
        VALUES (@num)
        SET @num = @num + 1
    end
    
  17. ==============================

    17.지수의 크기 재귀 CTE (심지어 100 재귀의 기본에 대해이 최대 2 ^ 100 번호를 구축 할 수 있습니다)

    지수의 크기 재귀 CTE (심지어 100 재귀의 기본에 대해이 최대 2 ^ 100 번호를 구축 할 수 있습니다)

    DECLARE @startnum INT=1000
    DECLARE @endnum INT=1050
    DECLARE @size INT=@endnum-@startnum+1
    ;
    WITH numrange (num) AS (
        SELECT 1 AS num
        UNION ALL
        SELECT num*2 FROM numrange WHERE num*2<=@size
        UNION ALL
        SELECT num*2+1 FROM numrange WHERE num*2+1<=@size
    )
    SELECT num+@startnum-1 FROM numrange order by num
    
  18. ==============================

    18.나는 유사한 방법을 사용하여 데이터베이스에 사진 파일 경로를 삽입했다. 가공 한 미세 아래의 쿼리 :

    나는 유사한 방법을 사용하여 데이터베이스에 사진 파일 경로를 삽입했다. 가공 한 미세 아래의 쿼리 :

    DECLARE @num INT = 8270058
    WHILE(@num<8270284)
    begin
        INSERT  INTO [dbo].[Galleries]
        (ImagePath) 
        VALUES 
        ('~/Content/Galeria/P'+CONVERT(varchar(10), @num)+'.JPG')
    
        SET @num = @num + 1
    end
    

    당신의 코드는 다음과 같습니다

    DECLARE @num INT = 1000
    WHILE(@num<1051)
    begin
        SELECT @num
    
        SET @num = @num + 1
    end
    
  19. ==============================

    19.

    -- Generate Numeric Range
    -- Source: http://www.sqlservercentral.com/scripts/Miscellaneous/30397/
    
    CREATE TABLE #NumRange(
        n int
    )
    
    DECLARE @MinNum int
    DECLARE @MaxNum int
    DECLARE @I int
    
    SET NOCOUNT ON
    
    SET @I = 0
    WHILE @I <= 9 BEGIN
        INSERT INTO #NumRange VALUES(@I)
        SET @I = @I + 1
    END
    
    
    SET @MinNum = 1
    SET @MaxNum = 1000000
    
    SELECT  num = a.n +
        (b.n * 10) +
        (c.n * 100) +
        (d.n * 1000) +
        (e.n * 10000)
    FROM    #NumRange a
    CROSS JOIN #NumRange b
    CROSS JOIN #NumRange c
    CROSS JOIN #NumRange d
    CROSS JOIN #NumRange e
    WHERE   a.n +
        (b.n * 10) +
        (c.n * 100) +
        (d.n * 1000) +
        (e.n * 10000) BETWEEN @MinNum AND @MaxNum
    ORDER BY a.n +
        (b.n * 10) +
        (c.n * 100) +
        (d.n * 1000) +
        (e.n * 10000) 
    
    DROP TABLE #NumRange
    
  20. ==============================

    20.이것은 단지 한 일부 응용 프로그램 테이블이 행이 같은 시퀀스 작동합니다. 내가 1..100에서 순서를한다고 가정하고, foo.bar (숫자 나 문자열 유형의) 열이있는 응용 프로그램 테이블 dbo.foo 있습니다 :

    이것은 단지 한 일부 응용 프로그램 테이블이 행이 같은 시퀀스 작동합니다. 내가 1..100에서 순서를한다고 가정하고, foo.bar (숫자 나 문자열 유형의) 열이있는 응용 프로그램 테이블 dbo.foo 있습니다 :

    select 
    top 100
    row_number() over (order by dbo.foo.bar) as seq
    from dbo.foo
    

    ORDER BY 절에있는 그것의 존재에도 불구하고, dbo.foo.bar는 별개의 또는 null 이외의 값을 가질 필요가 없습니다.

    물론, SQL 서버 2012 시퀀스 개체가 있으므로 해당 제품에 자연적인 해결책이있다.

  21. ==============================

    21.여기에 내가 무엇을 최대 온이다 :

    여기에 내가 무엇을 최대 온이다 :

    create or alter function dbo.fn_range(@start int, @end int)  returns table
    return
    with u2(n) as (
        select n 
        from (VALUES (0),(1),(2),(3)) v(n)
    ), 
    u8(n) as (
        select
            x0.n | x1.n * 4 | x2.n * 16 | x3.n * 64 as n
        from u2 x0, u2 x1, u2 x2, u2 x3
    )
    select 
        @start + s.n as n
    from (
        select
            x0.n | isnull(x1.n, 0) * 256 | isnull(x2.n, 0) * 65536 as n
        from u8 x0 
        left join u8 x1 on @end-@start > 256
        left join u8 x2 on @end-@start > 65536
    ) s
    where s.n < @end - @start
    

    2 ^ 24까지의 값을 생성한다. 조건은 작은 값을 빠르게 유지하세요.

  22. ==============================

    22.이것은 우리 DEV 서버 36 초 내 완료. 브라이언의 대답처럼, 범위 필터링에 집중하면 쿼리 내에서 중요하다 BETWEEN 여전히 그들을 필요로하지 않더라도 이전의 하한에 대한 모든 초기 레코드를 생성하려고합니다.

    이것은 우리 DEV 서버 36 초 내 완료. 브라이언의 대답처럼, 범위 필터링에 집중하면 쿼리 내에서 중요하다 BETWEEN 여전히 그들을 필요로하지 않더라도 이전의 하한에 대한 모든 초기 레코드를 생성하려고합니다.

    declare @s bigint = 10000000
        ,   @e bigint = 20000000
    
    ;WITH 
    Z AS (SELECT 0 z FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)) T(n)),
    Y AS (SELECT 0 z FROM Z a, Z b, Z c, Z d, Z e, Z f, Z g, Z h, Z i, Z j, Z k, Z l, Z m, Z n, Z o, Z p),
    N AS (SELECT ROW_NUMBER() OVER (PARTITION BY 0 ORDER BY z) n FROM Y)
    
    SELECT TOP (1+@e-@s) @s + n - 1 FROM N
    

    사용을하는 것이 우리가 어떤 방법으로 2 ^ 64 (== 16 ^ 16) 생성 된 기록을 통해 갈 수 있도록 참고 ROW_NUMBER는 BIGINT입니다. 이 질의는 생성 된 값에 따라서 동일한 상한을 존중한다.

  23. ==============================

    23.이 절차 적 코드와 테이블 반환 함수를 사용합니다. 천천히,하지만 쉽게 예측.

    이 절차 적 코드와 테이블 반환 함수를 사용합니다. 천천히,하지만 쉽게 예측.

    CREATE FUNCTION [dbo].[Sequence] (@start int, @end int)
    RETURNS
    @Result TABLE(ID int)
    AS
    begin
    declare @i int;
    set @i = @start;
    while @i <= @end 
        begin
            insert into @result values (@i);
            set @i = @i+1;
        end
    return;
    end
    

    용법:

    SELECT * FROM dbo.Sequence (3,7);
    ID
    3
    4
    5
    6
    7
    

    당신이 다른 데이터와 조인에 사용할 수 있도록 그것은 테이블입니다. A는 시간 값의 연속 순서를 보장하기 위해 시간, 일 등에 의해 그룹에 가입의 내가 가장 자주 왼쪽으로이 기능을 사용합니다.

    SELECT DateAdd(hh,ID,'2018-06-20 00:00:00') as HoursInTheDay FROM dbo.Sequence (0,23) ;
    
    HoursInTheDay
    2018-06-20 00:00:00.000
    2018-06-20 01:00:00.000
    2018-06-20 02:00:00.000
    2018-06-20 03:00:00.000
    2018-06-20 04:00:00.000
    (...)
    

    성능은 많은 목적을 위해 (16 만 행 초)하지만 좋은 충분히 기분이 우울합니다.

    SELECT count(1) FROM [dbo].[Sequence] (
       1000001
      ,2000000)
    GO
    
  24. ==============================

    24.오라클 12C; 빠른하지만 제한 :

    오라클 12C; 빠른하지만 제한 :

    select rownum+1000 from all_objects fetch first 50 rows only;
    

    참고 : ALL_OBJECTS보기의 행 수에 제한;

  25. ==============================

    25.이것은 매우 빠르고, 유연하고 코드가 아니라 많이 있어요, 내가 할 것입니다.

    이것은 매우 빠르고, 유연하고 코드가 아니라 많이 있어요, 내가 할 것입니다.

    DECLARE @count  int =   65536;
    DECLARE @start  int =   11;
    DECLARE @xml    xml =   REPLICATE(CAST('<x/>' AS nvarchar(max)), @count);
    
    ; WITH GenerateNumbers(Num) AS
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY @count) + @start - 1
        FROM    @xml.nodes('/x') X(T)
    )
    SELECT  Num
    FROM    GenerateNumbers;
    

    더미는 그 (@count BY ORDER)를 참고. 그것은 아무것도하지만, ROW_NUMBER ()에 의해 ORDER를 필요로하지 않습니다.

    편집하다: 나는 원래의 질문이 X에서 Y의 범위를 얻을 것을 깨달았다. 내 스크립트는 범위를 얻기 위해 다음과 같이 수정할 수 있습니다 :

    DECLARE @start  int =   5;
    DECLARE @end    int =   21;
    DECLARE @xml    xml =   REPLICATE(CAST('<x/>' AS nvarchar(max)), @end - @start + 1);
    
    ; WITH GenerateNumbers(Num) AS
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY @end) + @start - 1
        FROM    @xml.nodes('/x') X(T)
    )
    SELECT  Num
    FROM    GenerateNumbers;
    
  26. ==============================

    26.내가 개발 (다른 사람의 공유 작품의 일부를 타고) 지금 꽤 많은 시간 동안 사용했습니다 솔루션은 게시 된 적어도 하나의 약간 비슷합니다. 그것은 어떤 테이블을 참조하고 1048576 개 값 (2 ^ 20)까지의 범위를 정렬되지 않은 리턴 원하는 경우 원판을 포함 할 수 없다. 필요한 경우는 물론 정렬 결과의 수 있습니다. 그것은 특히 작은 범위에 꽤 빨리 실행됩니다.

    내가 개발 (다른 사람의 공유 작품의 일부를 타고) 지금 꽤 많은 시간 동안 사용했습니다 솔루션은 게시 된 적어도 하나의 약간 비슷합니다. 그것은 어떤 테이블을 참조하고 1048576 개 값 (2 ^ 20)까지의 범위를 정렬되지 않은 리턴 원하는 경우 원판을 포함 할 수 없다. 필요한 경우는 물론 정렬 결과의 수 있습니다. 그것은 특히 작은 범위에 꽤 빨리 실행됩니다.

    Select value from dbo.intRange(-500, 1500) order by value  -- returns 2001 values
    
    create function dbo.intRange 
    (   
        @Starting as int,
        @Ending as int
    )
    returns table
    as
    return (
        select value
        from (
            select @Starting +
                ( bit00.v | bit01.v | bit02.v | bit03.v
                | bit04.v | bit05.v | bit06.v | bit07.v
                | bit08.v | bit09.v | bit10.v | bit11.v
                | bit12.v | bit13.v | bit14.v | bit15.v
                | bit16.v | bit17.v | bit18.v | bit19.v
                ) as value
            from       (select 0 as v union ALL select 0x00001 as v) as bit00
            cross join (select 0 as v union ALL select 0x00002 as v) as bit01
            cross join (select 0 as v union ALL select 0x00004 as v) as bit02
            cross join (select 0 as v union ALL select 0x00008 as v) as bit03
            cross join (select 0 as v union ALL select 0x00010 as v) as bit04
            cross join (select 0 as v union ALL select 0x00020 as v) as bit05
            cross join (select 0 as v union ALL select 0x00040 as v) as bit06
            cross join (select 0 as v union ALL select 0x00080 as v) as bit07
            cross join (select 0 as v union ALL select 0x00100 as v) as bit08
            cross join (select 0 as v union ALL select 0x00200 as v) as bit09
            cross join (select 0 as v union ALL select 0x00400 as v) as bit10
            cross join (select 0 as v union ALL select 0x00800 as v) as bit11
            cross join (select 0 as v union ALL select 0x01000 as v) as bit12
            cross join (select 0 as v union ALL select 0x02000 as v) as bit13
            cross join (select 0 as v union ALL select 0x04000 as v) as bit14
            cross join (select 0 as v union ALL select 0x08000 as v) as bit15
            cross join (select 0 as v union ALL select 0x10000 as v) as bit16
            cross join (select 0 as v union ALL select 0x20000 as v) as bit17
            cross join (select 0 as v union ALL select 0x40000 as v) as bit18
            cross join (select 0 as v union ALL select 0x80000 as v) as bit19
        ) intList
        where @Ending - @Starting < 0x100000
            and intList.value between @Starting and @Ending
    )
    
  27. from https://stackoverflow.com/questions/21425546/how-to-generate-a-range-of-numbers-between-two-numbers by cc-by-sa and MIT license