Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SQL表中生成行以将一个范围拆分为单独的行_Sql_Sql Server_Loops - Fatal编程技术网

如何在SQL表中生成行以将一个范围拆分为单独的行

如何在SQL表中生成行以将一个范围拆分为单独的行,sql,sql-server,loops,Sql,Sql Server,Loops,我有类似以下信息的数据: Customer Start End AAA 100 399 BBB 400 899 CCC 900 999 AAA 1000 1199 我需要它变成两列,一列包含客户名称,另一列包含范围内的每个值。即 Customer Number AAA 100 AAA 101 AAA 102 ETC 这是如何用SQL编

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

Customer  Start   End
AAA        100    399 
BBB        400    899
CCC        900    999  
AAA        1000   1199
我需要它变成两列,一列包含客户名称,另一列包含范围内的每个值。即

Customer    Number
AAA           100
AAA           101
AAA           102   ETC

这是如何用SQL编写的?

我推荐的最佳方法是使用CTE进行递归。请查找下面的代码段来执行此操作

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)

如果您已经有一个数字表,请使用它。如果没有,您可以使用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    

有一个生成所有可能数字的cte。加入。你在使用什么关系数据库?sql是一种通用语言,每个数据库都使用自己特定的方言——因此,每当询问有关sql的问题时,请确保包含相关rdbms的标记。包含您正在使用的特定版本的标记也总是好的。使用这样的递归cte远不是最好的主意-有关更多信息,请阅读Jeff Moden的