This may not be possible, but I thought I'd throw it out here:
Given the following table:
ID, Begin, End
123, 1, N
Where N is an integer, write a query to return the following result set:
ID, Begin, End
123, 1, 1
123, 1, 2
123, 1, 3
.
.
.
123, 1, N
The platform we are using is SQL Server 2005, but if you can do it with another flavor of SQL, I'd still be interested in the solution.
try this:
create table #smalltable (id int, [begin] int, [end] int)
insert into #smalltable values (123,1,4)
insert into #smalltable values (124,1,12)
insert into #smalltable values (125,1,7)
;WITH digits (d) AS (
SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION
SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION
SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION
SELECT 0)
SELECT
s.id, s.[begin], n.Number AS [End]
FROM (SELECT i.d + ii.d * 10 + iii.d * 100 + iv.d * 1000 +
v.d * 10000 + vi.d * 100000 AS Number
FROM digits i
CROSS JOIN digits ii
CROSS JOIN digits iii
CROSS JOIN digits iv
CROSS JOIN digits v
CROSS JOIN digits vi
) AS N
INNER JOIN #smalltable s ON 1=1
INNER JOIN (SELECT MAX([end]) AS MaxEnd FROM #smalltable) dt ON 1=1
WHERE n.Number > 0 AND n.Number<=dt.MaxEnd
AND n.Number<=s.[end]
ORDER BY s.id,n.Number
comments
- don't name your columns the reserved words: "begin" and "end", you'll thank me some day.
- if you plan to run this in production many times, create a Numbers table
and use this query instead:
have to have a table Numbers before this will work (see link above)
SELECT
s.id,s.[begin],n.Number AS [End]
FROM Numbers n
INNER JOIN #smalltable s ON 1=1
WHERE n.Number > 0 AND n.Number<=s.[end]
ORDER BY s.id,number
it will run better.
Given some (theoretically infinite, but you could pre-populate) table Integers, containing all the integers, the answer is reasonably simple:
SELECT ID, Begin, I FROM YourTable, Integers
WHERE I <= Begin AND I >= End
With a clustered index on Integers.I, this should be pretty fast. You could pre-populate integers in a stored-proc (based on the result from SELECT max(End) FROM YourTable
).
This will work up to 99,999, and you can easily modify it to add more numbers. It needs no pre-existing numbers table and no stored procedure, and is still incredibly fast. Works on at least SQL Server 2000 and up, and is easily ported to other flavours of SQL:
select MyTable.ID, MyTable.[Begin], n.N
from (
select 123 as ID, 1 as [Begin], 9 as [End]
) MyTable
cross join (
select a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a) + (10000 * e.a) as N
from (select 0 as a union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) as a
cross join (select 0 as a union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) as b
cross join (select 0 as a union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) as c
cross join (select 0 as a union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) as d
cross join (select 0 as a union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) as e
) n
where n.N > 0
and n.N <= MyTable.[End]
order by n.N