根据 ID 将英里数限制为千分之一

SQL*_*ing 5 sql-server

我在 sql server 2014 中有一个这样的表:

ID | Start_mile|End_mile  
1  |5.23       |7.464  
2  |2.333      |6.124 
Run Code Online (Sandbox Code Playgroud)

我想要做的是将里程分成每个 ID 的千分之一,如下所示:

ID |start_mile|end_mile  
1  |5.230     |5.231  
1  |5.231     |5.232  
1  |5.232     |5.233  
....  
1  |7.463     |7.464  
...
Run Code Online (Sandbox Code Playgroud)

关于如何去做这件事的任何想法?我试图远离游标,除非这是唯一的方法。

我已经能够将这个查询放在一起,但不确定如何将它与 ID 和英里限制合并,以便它在没有声明的 From 和 To 变量的情况下为整个表运行:

DECLARE @from decimal(15, 3) = 0.980;  
DECLARE @to decimal(15, 3) = 1.024;  

;WITH cte AS  
    (SELECT @from AS Value  
     UNION ALL  
     SELECT CONVERT(decimal(15, 3), Value + 0.001)  
     FROM cte  
     WHERE Value < @to)  
SELECT *  
FROM cte  
option (maxrecursion 0) 
Run Code Online (Sandbox Code Playgroud)

Ran*_*gen 5

如果您不想使用递归 CTE,您可以使用以下查询示例:

SELECT m.ID, 
       a.rn as start_mile, 
       a.rn+ CONVERT(decimal(15, 3),0.001) as end_mile
FROM dbo.Miles m
CROSS APPLY
(
    SELECT TOP(CONVERT(int,(( end_mile -  Start_mile)* 1000)))
    CONVERT(decimal(15, 3),(Start_mile + (CONVERT(decimal(15, 3),ROW_NUMBER() OVER(ORDER BY (SELECT NULL))-1) / 1000))) as rn
    FROM master..spt_values spt1
    CROSS APPLY master..spt_values spt2
) as a;
Run Code Online (Sandbox Code Playgroud)

对于一个 ID,这应该可以运行到600 万英里。

spt 值表可以替换为某种数字表。

数据库<>小提琴


Mat*_*DBA 4

您只需要引用锚点中的​​初始开始值和结束值。

CREATE TABLE #tmp (
    ID INT NOT NULL PRIMARY KEY
    ,[Start] DECIMAL(15, 3)
    ,[To] DECIMAL(15, 3)
    )
GO
INSERT INTO #tmp (
    ID
    ,[Start]
    ,[To]
    )
VALUES (
    1
    ,5.00
    ,5.99
    )
    ,(
    2
    ,10.00
    ,10.4
    );
WITH cte
AS (
    SELECT ID
        ,[Start]
        ,[To]
        ,CAST([Start] AS DECIMAL(15, 3)) AS [Value]
    FROM #tmp

    UNION ALL

    SELECT ID
        ,[Start]
        ,[To]
        ,CAST(([Value] + 0.001) AS DECIMAL(15, 3))
    FROM cte
    WHERE CAST(([Value] + 0.001) AS DECIMAL(15, 3)) < [To]
    )
SELECT *
FROM cte
ORDER BY ID
    ,Start
    ,Value
OPTION (MAXRECURSION 0)
Run Code Online (Sandbox Code Playgroud)