HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlMinor

Split mile limits to the thousandth based on ID

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
thethousandthlimitssplitbasedmile

Problem

I have a table like this in sql server 2014:

ID | Start_mile|End_mile  
1  |5.23       |7.464  
2  |2.333      |6.124


What I want to do is to split the miles into thousandths per ID like this:

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  
...


Any ideas as to how to go about doing this? I am trying to stay away from Cursors, unless that's the only way to do this.

I have been able to get this query together , but not sure how to incorporate it with the ID, and mile limits I have so that it runs for the whole table without the declared From and To variables:

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)

Solution

If you don't want to use a recursive CTE you could use below query example:

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;


This should work up until 6M miles for one id.

The spt values table could be replaced by a numbers table of some sort.

DB<>Fiddle

Code Snippets

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;

Context

StackExchange Database Administrators Q#250573, answer score: 5

Revisions (0)

No revisions yet.