How to generate a range of numbers between two numbers?

后端 未结 30 1870
执念已碎
执念已碎 2020-11-22 10:16

I have two numbers as input from the user, like for example 1000 and 1050.

How do I generate the numbers between these two numbers, using

相关标签:
30条回答
  • 2020-11-22 10:18

    The solution I've developed and used for quite some time now (riding some on the shared works of others) is slightly similar to at least one posted. It doesn't reference any tables and returns an unsorted range of up to 1048576 values (2^20) and can include negatives if desired. You can of course sort the result if necessary. It runs pretty quickly, especially on smaller ranges.

    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
    )
    
    0 讨论(0)
  • 2020-11-22 10:19

    The best option I have used is as follows:

    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
    

    I have generated millions of records using this and it works perfect.

    0 讨论(0)
  • 2020-11-22 10:19

    I had to insert picture filepath into database using similar method. The query below worked fine:

    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
    

    The code for you would be:

    DECLARE @num INT = 1000
    WHILE(@num<1051)
    begin
        SELECT @num
    
        SET @num = @num + 1
    end
    
    0 讨论(0)
  • 2020-11-22 10:20

    2 years later, but I found I had the same issue. Here is how I solved it. (edited to include parameters)

    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)
    
    0 讨论(0)
  • 2020-11-22 10:20
    ;WITH u AS (
        SELECT Unit FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) v(Unit)
    ),
    d AS (
        SELECT 
            (Thousands+Hundreds+Tens+Units) V
        FROM 
               (SELECT Thousands = Unit * 1000 FROM u) Thousands 
               ,(SELECT Hundreds = Unit * 100 FROM u) Hundreds 
               ,(SELECT Tens = Unit * 10 FROM u) Tens 
               ,(SELECT Units = Unit FROM u) Units
        WHERE
               (Thousands+Hundreds+Tens+Units) <= 10000
    )
    
    SELECT * FROM d ORDER BY v
    
    0 讨论(0)
  • 2020-11-22 10:21

    Select non-persisted values with the VALUES keyword. Then use JOINs to generate lots and lots of combinations (can be extended to create hundreds of thousands of rows and beyond).

    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
    

    Demo

    A shorter alternative, that is not as easy to understand:

    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
    

    Demo

    0 讨论(0)
提交回复
热议问题