首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在范围间生成数字

在范围间生成数字
EN

Stack Overflow用户
提问于 2017-02-15 08:23:09
回答 3查看 700关注 0票数 2

假设我有2-6,通过使用下面的程序,我可以生成范围

代码语言:javascript
运行
复制
DECLARE @range VARCHAR(10) = '2-6'
DECLARE @startRange INT = PARSENAME(REPLACE(@range, '-', '.'), 2)
DECLARE @lastRange INT = PARSENAME(REPLACE(@range, '-', '.'), 1)

SELECT DISTINCT Number = number
FROM master..spt_values
WHERE number BETWEEN @startRange AND @lastRange

现在我以2-6,9-12,15-20的形式输入

我知道,通过使用,作为分隔器分割记录,并使用上面的查询作为函数,我可以达到目标。不过,我想用交叉申请它来避免功能。

我已经试过了

代码语言:javascript
运行
复制
DECLARE @range VARCHAR(50) = '2-6,9-12,15-20'

SELECT
    value   
FROM STRING_SPLIT(@range,',')

但如何将交叉应用与上述查询与master..spt_values结合使用

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-02-15 08:32:40

如果您只提取每个项目的开始和结束位置,则可以使用以下内容:

代码语言:javascript
运行
复制
DECLARE @Value VARCHAR(20) = '2-6';

SELECT  Start = TRY_CONVERT(INT, LEFT(@Value, CHARINDEX('-', @Value) - 1)),
        [End] = TRY_CONVERT(INT, SUBSTRING(@Value, CHARINDEX('-', @Value) + 1, LEN(@Value)));

这意味着:

代码语言:javascript
运行
复制
Start   End
------------
2       6

然后,您可以简单地加入到master..spt_values

代码语言:javascript
运行
复制
DECLARE @range VARCHAR(50) = '2-6,9-12,15-20'

SELECT  s.Value, v.Number
FROM    STRING_SPLIT(@range,',') AS s
        INNER JOIN master..spt_values AS v
            ON v.Number >= TRY_CONVERT(INT, LEFT(s.Value, CHARINDEX('-', s.Value) - 1))
            AND v.Number <= TRY_CONVERT(INT, SUBSTRING(s.Value, CHARINDEX('-', s.Value) + 1, LEN(s.Value)))
            AND v.Type = 'P';

由于master..spt_values的价值相当有限,所以有更好的方法来实现生成没有循环的集合或序列

当使用master..spt_values时,范围2500-2501不起作用,但是如果您有一个数字表,或者一个不同的数字来源,就可以了,例如,下面的工作最多可达10,000个,然后通过去掉注释,您可以增加范围:

代码语言:javascript
运行
复制
DECLARE @range VARCHAR(50) = '2-6,9-12,15-20,2500-2501';

WITH Numbers (Number) AS
(   SELECT  ROW_NUMBER() OVER(ORDER BY N1.N)
    FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS N1 (N)         -- 100
    CROSS JOIN (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS N2 (N)   -- 100
    CROSS JOIN (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS N3 (N)   -- 1,000
    CROSS JOIN (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS N4 (N)   -- 10,000
    --CROSS JOIN (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS N5 (N) -- 100,000
)
SELECT  s.Value, n.Number
FROM    STRING_SPLIT(@range,',') AS s
        INNER JOIN Numbers AS n
            ON n.Number >= TRY_CONVERT(INT, LEFT(s.Value, CHARINDEX('-', s.Value) - 1))
            AND n.Number <= TRY_CONVERT(INT, SUBSTRING(s.Value, CHARINDEX('-', s.Value) + 1, LEN(s.Value)))
ORDER BY n.Number;
票数 3
EN

Stack Overflow用户

发布于 2017-02-15 08:38:06

您可以使用以下脚本实现此结果

代码语言:javascript
运行
复制
SELECT DISTINCT Number = number
FROM master..spt_values
    CROSS APPLY STRING_SPLIT(@range,',') AS S
WHERE number BETWEEN PARSENAME(REPLACE(value, '-', '.'), 2) 
                AND PARSENAME(REPLACE(value, '-', '.'), 1)
票数 1
EN

Stack Overflow用户

发布于 2017-02-15 08:48:56

交叉应用版本

代码语言:javascript
运行
复制
SELECT t.number     
FROM STRING_SPLIT(@range,',') sv
CROSS APPLY (
    SELECT startv = CAST(PARSENAME(REPLACE(value, '-', '.'), 2) AS INT),
           endv = CAST(PARSENAME(REPLACE(value, '-', '.'), 1) AS INT)             
) param
CROSS APPLY (
   SELECT TOP(endv-startv+1) number = startv + row_number() over(order by startv) - 1
   FROM master..spt_values
) t;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42244038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档