Is there a generic way to generate an arbitrary linear sequence in SQL?

前端 未结 6 979
被撕碎了的回忆
被撕碎了的回忆 2021-01-13 02:37

Is there a SQL query I can do that will generate a linear sequence like

1, 2, 3, 4, 5, 6, 7 ... x+1

or

2, 7, 12, 17, 22 ...         


        
6条回答
  •  梦谈多话
    2021-01-13 02:47

    If performance is your concern, have this UDF ready:

    create function [dbo].[Numbers](@count bigint)
    RETURNS TABLE RETURN
    with byte (n) as ( select 1 from ( VALUES 
            (1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ,(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)
            ) x(n)  )
    , byte2 (n) as ( select 1 from byte a, byte b)
    , byte4 (n) as ( select 1 from byte2 a, byte2 b)
    , byte8 (n) as ( select 1 from byte4 a, byte4 b)
    select top(@count) n = ROW_NUMBER() over(order by n) from byte8
    

    Apparently, recursion-only CTE generated number sequence works, but very slow. Here we trade some code volume for huge increase in performance. This one gives me over 30 million numbers in 8 seconds on my crappy overloaded PC. It can go as far as you want and can afford to the limit of max bigint.

    It won't touch the disk IO unless the optimizer rules it out of memory (hardly ever for reasonable scenario). It will also avoid waits and deadlocks unlike solutions based on physical tables.

    Use like this:

    select 2 + n*5 from Numbers(100)
    

    You should be able to create a view like this.

    For those not requiring an actual number, just rows, removing the row_number stuff speeds it up twice.

    Inspired by http://weblogs.sqlteam.com/jamesn/archive/2008/05/29/60612.aspx (Itzik Ben Gan mentioned by S. Neumann). This version comes with a simpler execution plan and makes bigints possible, that's about the advantages.

提交回复
热议问题