【问题标题】:How can I generate rows in a SQL table to break up a range into induvidual rows如何在 SQL 表中生成行以将范围分解为单独的行
【发布时间】:2023-03-21 18:13:01
【问题描述】:

我有类似于以下信息的数据:

Customer  Start   End
AAA        100    399 
BBB        400    899
CCC        900    999  
AAA        1000   1199

我需要它变成 2 列,1 列带有客户名称,另一列带有范围内的每个值。即。

Customer    Number
AAA           100
AAA           101
AAA           102   ETC

这怎么能用 SQL 来写呢?

【问题讨论】:

  • 有一个可以产生所有可能数字的 cte。加入。
  • 您使用的是什么 rdbms? sql 是一种通用语言,每个数据库都使用它自己的特定方言 - 因此,每当询问有关 sql 的问题时,请务必包含相关 rdbms 的标签。包含您正在使用的特定版本的标签也总是很好的。

标签: sql sql-server loops


【解决方案1】:

如果您已经有一个数字表,请使用它。如果没有,您可以使用 cte 动态生成数字表。

首先,创建并填充示例表(在您以后的问题中保存我们这一步):

DECLARE @T AS TABLE
(
    Customer char(3),
    Start int,
    [End] int
);

INSERT INTO @T(Customer, Start, [End]) VALUES
('AAA', 100, 399), 
('BBB', 400, 899),
('CCC', 900, 999),  
('AAA', 1000, 1199);

然后,使用 cte 生成您需要的数字

WITH Tally(n) AS
(
    SELECT TOP(select max([End]) from @T) ROW_NUMBER() OVER(ORDER BY @@SPID) 
    FROM sys.objects
)

最后,从加入cte的表中选择:

SELECT Customer, n
FROM @T
JOIN Tally 
    ON n >= Start
    AND n <= [End]
ORDER BY Customer, n    

【讨论】:

    【解决方案2】:

    我推荐的最佳方法是使用 CTE 进行递归。请找下面的代码sn-p来做。

    declare @source table (customer varchar(15), rangeStart int, rangeEnd int)
    
    insert into @source (customer, rangeStart, rangeEnd)
    select 'AAA', 100, 399
    union
    select 'BBB', 400, 899
    union
    select 'CCC', 900, 999
    union
    select 'AAA', 1000, 1199
    
    
    select * from @source
    
    ; with results as (
        select Customer, rangeStart, rangeEnd, rangeNumber = rangeStart
            from @source
        union all
        select Customer, rangeStart, rangeEnd, rangeNumber + 1
            from results
            where rangeNumber <= rangeEnd
    
    )
    
    select * 
        from results 
        order by rangeNumber
        option (MAXRECURSION 20000)
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-19
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多