[SQL] 어떻게 두 숫자 사이의 숫자의 범위를 생성하는?
SQL어떻게 두 숫자 사이의 숫자의 범위를 생성하는?
I는, 예를 들면 1000, 1050와 같이, 사용자로부터 입력 된 두 개의 번호를 갖는다.
어떻게 별도의 행에, SQL 쿼리를 사용하여,이 두 숫자 사이의 번호를 생성합니까? 나는이 원하는 :
1000
1001
1002
1003
.
.
1050
해결법
-
==============================
1.값 키워드와 비 지속 값을 선택합니다. 그런 다음 사용이 많은 조합을 많이 생성하는 조인 (행 이후 수십만를 만들 확장 할 수 있습니다).
값 키워드와 비 지속 값을 선택합니다. 그런 다음 사용이 많은 조합을 많이 생성하는 조인 (행 이후 수십만를 만들 확장 할 수 있습니다).
SELECT ones.n + 10*tens.n + 100*hundreds.n + 1000*thousands.n FROM (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) ones(n), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) tens(n), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) hundreds(n), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) thousands(n) WHERE ones.n + 10*tens.n + 100*hundreds.n + 1000*thousands.n BETWEEN @userinput1 AND @userinput2 ORDER BY 1
데모
쉽게로되지 않는 짧은 대안은 이해하기 :
WITH x AS (SELECT n FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) v(n)) SELECT ones.n + 10*tens.n + 100*hundreds.n + 1000*thousands.n FROM x ones, x tens, x hundreds, x thousands ORDER BY 1
데모
-
==============================
2.대체 솔루션은 재귀 CTE는 다음과 같습니다
대체 솔루션은 재귀 CTE는 다음과 같습니다
DECLARE @startnum INT=1000 DECLARE @endnum INT=1050 ; WITH gen AS ( SELECT @startnum AS num UNION ALL SELECT num+1 FROM gen WHERE num+1<=@endnum ) SELECT * FROM gen option (maxrecursion 10000)
-
==============================
3.
SELECT DISTINCT n = number FROM master..[spt_values] WHERE number BETWEEN @start AND @end
데모
다음 숫자가 차이가 있기 때문에이 테이블 2048의 최대를 가지고 있습니다.
여기 (SQL-서버 2005 이후) 시스템 뷰를 사용하여 약간 더 나은 방법입니다 :
;WITH Nums AS ( SELECT n = ROW_NUMBER() OVER (ORDER BY [object_id]) FROM sys.all_objects ) SELECT n FROM Nums WHERE n BETWEEN @start AND @end ORDER BY n;
데모
또는 사용자 정의 a를 번호 테이블을 사용합니다. 아론 버트 랜드에 학점, 나는 전체 기사를 읽고하는 것이 좋습니다 : 루프없이 세트 또는 시퀀스를 생성
-
==============================
4.나는 최근에 바로이 문제를 해결하기 위해이 인라인 테이블 반환 함수를 썼다. 그것은 메모리와 저장 이외의 범위에 제한 아니에요. 읽거나 일반적으로 쓰는 디스크에 대한 필요가 없습니다 그래서 더 테이블에 액세스하지 않습니다. 그것은 매우 큰 범위에 대해서도 매우 빠른 그래서이 반복 될 때마다 기하 급수적으로 값을 조인 추가합니다. 그것은 내 서버에 5 초 천만 레코드를 작성합니다. 또한 음의 값으로 작동합니다.
나는 최근에 바로이 문제를 해결하기 위해이 인라인 테이블 반환 함수를 썼다. 그것은 메모리와 저장 이외의 범위에 제한 아니에요. 읽거나 일반적으로 쓰는 디스크에 대한 필요가 없습니다 그래서 더 테이블에 액세스하지 않습니다. 그것은 매우 큰 범위에 대해서도 매우 빠른 그래서이 반복 될 때마다 기하 급수적으로 값을 조인 추가합니다. 그것은 내 서버에 5 초 천만 레코드를 작성합니다. 또한 음의 값으로 작동합니다.
CREATE FUNCTION [dbo].[fn_ConsecutiveNumbers] ( @start int, @end int ) RETURNS TABLE RETURN select x268435456.X | x16777216.X | x1048576.X | x65536.X | x4096.X | x256.X | x16.X | x1.X + @start X from (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)) as x1(X) join (VALUES (0),(16),(32),(48),(64),(80),(96),(112),(128),(144),(160),(176),(192),(208),(224),(240)) as x16(X) on x1.X <= @end-@start and x16.X <= @end-@start join (VALUES (0),(256),(512),(768),(1024),(1280),(1536),(1792),(2048),(2304),(2560),(2816),(3072),(3328),(3584),(3840)) as x256(X) on x256.X <= @end-@start join (VALUES (0),(4096),(8192),(12288),(16384),(20480),(24576),(28672),(32768),(36864),(40960),(45056),(49152),(53248),(57344),(61440)) as x4096(X) on x4096.X <= @end-@start join (VALUES (0),(65536),(131072),(196608),(262144),(327680),(393216),(458752),(524288),(589824),(655360),(720896),(786432),(851968),(917504),(983040)) as x65536(X) on x65536.X <= @end-@start join (VALUES (0),(1048576),(2097152),(3145728),(4194304),(5242880),(6291456),(7340032),(8388608),(9437184),(10485760),(11534336),(12582912),(13631488),(14680064),(15728640)) as x1048576(X) on x1048576.X <= @end-@start join (VALUES (0),(16777216),(33554432),(50331648),(67108864),(83886080),(100663296),(117440512),(134217728),(150994944),(167772160),(184549376),(201326592),(218103808),(234881024),(251658240)) as x16777216(X) on x16777216.X <= @end-@start join (VALUES (0),(268435456),(536870912),(805306368),(1073741824),(1342177280),(1610612736),(1879048192)) as x268435456(X) on x268435456.X <= @end-@start WHERE @end >= x268435456.X | isnull(x16777216.X, 0) | isnull(x1048576.X, 0) | isnull(x65536.X, 0) | isnull(x4096.X, 0) | isnull(x256.X, 0) | isnull(x16.X, 0) | isnull(x1.X, 0) + @start GO SELECT X FROM fn_ConsecutiveNumbers(5, 500);
그것은뿐만 아니라 날짜와 시간 범위에 대해 편리합니다 :
SELECT DATEADD(day,X, 0) DayX FROM fn_ConsecutiveNumbers(datediff(day,0,'5/8/2015'), datediff(day,0,'5/31/2015')) SELECT DATEADD(hour,X, 0) HourX FROM fn_ConsecutiveNumbers(datediff(hour,0,'5/8/2015'), datediff(hour,0,'5/8/2015 12:00 PM'));
당신은 크로스 테이블의 값을 기준으로 분할 기록에 조인 적용 사용할 수 있습니다. 그래서 예를 들어 당신이 좋아하는 일을 할 수있는 테이블의 시간 범위에있는 모든 분에 대한 기록을 만들 수 있습니다 :
select TimeRanges.StartTime, TimeRanges.EndTime, DATEADD(minute,X, 0) MinuteX FROM TimeRanges cross apply fn_ConsecutiveNumbers(datediff(hour,0,TimeRanges.StartTime), datediff(hour,0,TimeRanges.EndTime)) ConsecutiveNumbers
-
==============================
5.다음과 같이 내가 사용한 가장 좋은 방법은 다음과 같습니다
다음과 같이 내가 사용한 가장 좋은 방법은 다음과 같습니다
DECLARE @min bigint, @max bigint SELECT @Min=919859000000 ,@Max=919859999999 SELECT TOP (@Max-@Min+1) @Min-1+row_number() over(order by t1.number) as N FROM master..spt_values t1 CROSS JOIN master..spt_values t2
나는 이것을 사용하여 수백만 개의 레코드를 생성하고 그것을 완벽하게 작동합니다.
-
==============================
6.그것은 나를 위해 작동!
그것은 나를 위해 작동!
select top 50 ROW_NUMBER() over(order by a.name) + 1000 as Rcount from sys.all_objects a
-
==============================
7.가장 좋은 방법은 재귀 CTE를 사용하고 있습니다.
가장 좋은 방법은 재귀 CTE를 사용하고 있습니다.
declare @initial as int = 1000; declare @final as int =1050; with cte_n as ( select @initial as contador union all select contador+1 from cte_n where contador <@final ) select * from cte_n option (maxrecursion 0)
인사.
-
==============================
8.
declare @start int = 1000 declare @end int =1050 ;with numcte AS ( SELECT @start [SEQUENCE] UNION all SELECT [SEQUENCE] + 1 FROM numcte WHERE [SEQUENCE] < @end ) SELECT * FROM numcte
-
==============================
9.당신은 좋은 옵션은 .NET에서 테이블 반환 함수를 작성하는 서버에 어셈블리 CLR을 설치 문제가없는 경우. 그런 식으로 당신은 쉽게 다른 쿼리와 그 결과가 스트리밍되기 때문에 메모리를 낭비하지 않습니다 보너스로 가입하고, 간단한 구문을 사용할 수 있습니다.
당신은 좋은 옵션은 .NET에서 테이블 반환 함수를 작성하는 서버에 어셈블리 CLR을 설치 문제가없는 경우. 그런 식으로 당신은 쉽게 다른 쿼리와 그 결과가 스트리밍되기 때문에 메모리를 낭비하지 않습니다 보너스로 가입하고, 간단한 구문을 사용할 수 있습니다.
다음 클래스를 포함하는 프로젝트를 생성합니다 :
using System; using System.Collections; using System.Data; using System.Data.Sql; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; namespace YourNamespace { public sealed class SequenceGenerator { [SqlFunction(FillRowMethodName = "FillRow")] public static IEnumerable Generate(SqlInt32 start, SqlInt32 end) { int _start = start.Value; int _end = end.Value; for (int i = _start; i <= _end; i++) yield return i; } public static void FillRow(Object obj, out int i) { i = (int)obj; } private SequenceGenerator() { } } }
서버와 실행에 조립 어딘가에 넣어 :
USE db; CREATE ASSEMBLY SqlUtil FROM 'c:\path\to\assembly.dll' WITH permission_set=Safe; CREATE FUNCTION [Seq](@start int, @end int) RETURNS TABLE(i int) AS EXTERNAL NAME [SqlUtil].[YourNamespace.SequenceGenerator].[Generate];
지금 당신은 실행할 수 있습니다 :
select * from dbo.seq(1, 1000000)
-
==============================
10.아무것도 새로운하지만 눈에 쉽게 될 브라이언 프레슬러 솔루션을 재 작성, 누군가 (그냥 미래의 나를 경우에도)에 유용 할 수 있습니다 :
아무것도 새로운하지만 눈에 쉽게 될 브라이언 프레슬러 솔루션을 재 작성, 누군가 (그냥 미래의 나를 경우에도)에 유용 할 수 있습니다 :
alter function [dbo].[fn_GenerateNumbers] ( @start int, @end int ) returns table return with b0 as (select n from (values (0),(0x00000001),(0x00000002),(0x00000003),(0x00000004),(0x00000005),(0x00000006),(0x00000007),(0x00000008),(0x00000009),(0x0000000A),(0x0000000B),(0x0000000C),(0x0000000D),(0x0000000E),(0x0000000F)) as b0(n)), b1 as (select n from (values (0),(0x00000010),(0x00000020),(0x00000030),(0x00000040),(0x00000050),(0x00000060),(0x00000070),(0x00000080),(0x00000090),(0x000000A0),(0x000000B0),(0x000000C0),(0x000000D0),(0x000000E0),(0x000000F0)) as b1(n)), b2 as (select n from (values (0),(0x00000100),(0x00000200),(0x00000300),(0x00000400),(0x00000500),(0x00000600),(0x00000700),(0x00000800),(0x00000900),(0x00000A00),(0x00000B00),(0x00000C00),(0x00000D00),(0x00000E00),(0x00000F00)) as b2(n)), b3 as (select n from (values (0),(0x00001000),(0x00002000),(0x00003000),(0x00004000),(0x00005000),(0x00006000),(0x00007000),(0x00008000),(0x00009000),(0x0000A000),(0x0000B000),(0x0000C000),(0x0000D000),(0x0000E000),(0x0000F000)) as b3(n)), b4 as (select n from (values (0),(0x00010000),(0x00020000),(0x00030000),(0x00040000),(0x00050000),(0x00060000),(0x00070000),(0x00080000),(0x00090000),(0x000A0000),(0x000B0000),(0x000C0000),(0x000D0000),(0x000E0000),(0x000F0000)) as b4(n)), b5 as (select n from (values (0),(0x00100000),(0x00200000),(0x00300000),(0x00400000),(0x00500000),(0x00600000),(0x00700000),(0x00800000),(0x00900000),(0x00A00000),(0x00B00000),(0x00C00000),(0x00D00000),(0x00E00000),(0x00F00000)) as b5(n)), b6 as (select n from (values (0),(0x01000000),(0x02000000),(0x03000000),(0x04000000),(0x05000000),(0x06000000),(0x07000000),(0x08000000),(0x09000000),(0x0A000000),(0x0B000000),(0x0C000000),(0x0D000000),(0x0E000000),(0x0F000000)) as b6(n)), b7 as (select n from (values (0),(0x10000000),(0x20000000),(0x30000000),(0x40000000),(0x50000000),(0x60000000),(0x70000000)) as b7(n)) select s.n from ( select b7.n | b6.n | b5.n | b4.n | b3.n | b2.n | b1.n | b0.n + @start n from b0 join b1 on b0.n <= @end-@start and b1.n <= @end-@start join b2 on b2.n <= @end-@start join b3 on b3.n <= @end-@start join b4 on b4.n <= @end-@start join b5 on b5.n <= @end-@start join b6 on b6.n <= @end-@start join b7 on b7.n <= @end-@start ) s where @end >= s.n GO
-
==============================
11.나중에 2 년,하지만 난 같은 문제가 있었다 발견했다. 여기에 내가 그것을 해결하는 방법입니다. (파라미터를 포함하도록 수정)
나중에 2 년,하지만 난 같은 문제가 있었다 발견했다. 여기에 내가 그것을 해결하는 방법입니다. (파라미터를 포함하도록 수정)
DECLARE @Start INT, @End INT SET @Start = 1000 SET @End = 1050 SELECT TOP (@End - @Start+1) ROW_NUMBER() OVER (ORDER BY S.[object_id])+(@Start - 1) [Numbers] FROM sys.all_objects S WITH (NOLOCK)
-
==============================
12.여기에 몇 가지 아주 최적의 호환 솔루션은 다음과 같습니다 :
여기에 몇 가지 아주 최적의 호환 솔루션은 다음과 같습니다 :
USE master; declare @min as int; set @min = 1000; declare @max as int; set @max = 1050; --null returns all -- Up to 256 - 2 048 rows depending on SQL Server version select isnull(@min,0)+number.number as number FROM dbo.spt_values AS number WHERE number."type" = 'P' --integers and ( @max is null --return all or isnull(@min,0)+number.number <= @max --return up to max ) order by number ; -- Up to 65 536 - 4 194 303 rows depending on SQL Server version select isnull(@min,0)+value1.number+(value2.number*numberCount.numbers) as number FROM dbo.spt_values AS value1 cross join dbo.spt_values AS value2 cross join ( --get the number of numbers (depends on version) select sum(1) as numbers from dbo.spt_values where spt_values."type" = 'P' --integers ) as numberCount WHERE value1."type" = 'P' --integers and value2."type" = 'P' --integers and ( @max is null --return all or isnull(@min,0)+value1.number+(value2.number*numberCount.numbers) <= @max --return up to max ) order by number ;
-
==============================
13.slartidan의 대답은 데카르트 제품에 대한 모든 참조를 제거하고 ROW_NUMBER () 대신 (실행 계획 비교)을 사용하여, 현명한 성능을 향상시킬 수 :
slartidan의 대답은 데카르트 제품에 대한 모든 참조를 제거하고 ROW_NUMBER () 대신 (실행 계획 비교)을 사용하여, 현명한 성능을 향상시킬 수 :
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x1(x), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x2(x), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x3(x), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x4(x), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x5(x) ORDER BY n
CTE를 내부를 감싸고 원하는 번호를 선택하는 where 절을 추가합니다 :
DECLARE @n1 AS INT = 100; DECLARE @n2 AS INT = 40099; WITH numbers AS ( SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x1(x), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x2(x), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x3(x), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x4(x), (VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) x5(x) ) SELECT numbers.n FROM numbers WHERE n BETWEEN @n1 and @n2 ORDER BY n
-
==============================
14.내가 너무 늦게 사년이야 알지만,이 문제에 대한 또 다른 대안 대답 우연히. 속도 문제는 사전에 필터링되지 않고, 또한 정렬을 방지 할 수있다. 그것은 데카르트의 제품이 실제로 조인의 결과로 계산하는 방식으로 실행하는 조인 순서를 강제하는 것이 가능하다. 점프 - 오프 포인트로 slartidan의 답변을 사용 :
내가 너무 늦게 사년이야 알지만,이 문제에 대한 또 다른 대안 대답 우연히. 속도 문제는 사전에 필터링되지 않고, 또한 정렬을 방지 할 수있다. 그것은 데카르트의 제품이 실제로 조인의 결과로 계산하는 방식으로 실행하는 조인 순서를 강제하는 것이 가능하다. 점프 - 오프 포인트로 slartidan의 답변을 사용 :
WITH x AS (SELECT n FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) v(n)) SELECT ones.n + 10*tens.n + 100*hundreds.n + 1000*thousands.n FROM x ones, x tens, x hundreds, x thousands ORDER BY 1
우리는 우리가 원하는 범위를 알고 있다면, 우리는 @Upper 및 @Lower 통해 지정할 수 있습니다. (가) REMOTE TOP과 함께 조인 힌트를 결합함으로써, 우리는 우리가 낭비 아무것도 원하는 값의 하위 집합을 계산할 수 있습니다.
WITH x AS (SELECT n FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) v(n)) SELECT TOP (1+@Upper-@Lower) @Lower + ones.n + 10*tens.n + 100*hundreds.n + 1000*thousands.n FROM x thousands INNER REMOTE JOIN x hundreds on 1=1 INNER REMOTE JOIN x tens on 1=1 INNER REMOTE JOIN x ones on 1=1
는 옵티마이의 오른쪽에 비교하는 힌트 REMOTE 세력이 먼저 조인. 각 원격으로 가입 지정함으로써 대부분의 최하위 값은 그 자체가 정확하게 의해 위쪽으로 계산한다 조인. 주문 BY로 정렬합니다 WHERE 또는과 필터 필요가 없습니다.
당신이 범위를 늘리려면 그들이 FROM 절에서 최하위에 가장에서 주문하고, 당신은 너무 오래, 크기 점진적으로 더 높은 순서로 조인 추가를 계속 추가 할 수 있습니다.
이 SQL Server 2008 또는 이상으로 쿼리 특정합니다.
-
==============================
15.이것은 또한 할 것
이것은 또한 할 것
DECLARE @startNum INT = 1000; DECLARE @endNum INT = 1050; INSERT INTO dbo.Numbers ( Num ) SELECT CASE WHEN MAX(Num) IS NULL THEN @startNum ELSE MAX(Num) + 1 END AS Num FROM dbo.Numbers GO 51
-
==============================
16.최고 속도 실행시 쿼리
최고 속도 실행시 쿼리
DECLARE @num INT = 1000 WHILE(@num<1050) begin INSERT INTO [dbo].[Codes] ( Code ) VALUES (@num) SET @num = @num + 1 end
-
==============================
17.지수의 크기 재귀 CTE (심지어 100 재귀의 기본에 대해이 최대 2 ^ 100 번호를 구축 할 수 있습니다)
지수의 크기 재귀 CTE (심지어 100 재귀의 기본에 대해이 최대 2 ^ 100 번호를 구축 할 수 있습니다)
DECLARE @startnum INT=1000 DECLARE @endnum INT=1050 DECLARE @size INT=@endnum-@startnum+1 ; WITH numrange (num) AS ( SELECT 1 AS num UNION ALL SELECT num*2 FROM numrange WHERE num*2<=@size UNION ALL SELECT num*2+1 FROM numrange WHERE num*2+1<=@size ) SELECT num+@startnum-1 FROM numrange order by num
-
==============================
18.나는 유사한 방법을 사용하여 데이터베이스에 사진 파일 경로를 삽입했다. 가공 한 미세 아래의 쿼리 :
나는 유사한 방법을 사용하여 데이터베이스에 사진 파일 경로를 삽입했다. 가공 한 미세 아래의 쿼리 :
DECLARE @num INT = 8270058 WHILE(@num<8270284) begin INSERT INTO [dbo].[Galleries] (ImagePath) VALUES ('~/Content/Galeria/P'+CONVERT(varchar(10), @num)+'.JPG') SET @num = @num + 1 end
당신의 코드는 다음과 같습니다
DECLARE @num INT = 1000 WHILE(@num<1051) begin SELECT @num SET @num = @num + 1 end
-
==============================
19.
-- Generate Numeric Range -- Source: http://www.sqlservercentral.com/scripts/Miscellaneous/30397/ CREATE TABLE #NumRange( n int ) DECLARE @MinNum int DECLARE @MaxNum int DECLARE @I int SET NOCOUNT ON SET @I = 0 WHILE @I <= 9 BEGIN INSERT INTO #NumRange VALUES(@I) SET @I = @I + 1 END SET @MinNum = 1 SET @MaxNum = 1000000 SELECT num = a.n + (b.n * 10) + (c.n * 100) + (d.n * 1000) + (e.n * 10000) FROM #NumRange a CROSS JOIN #NumRange b CROSS JOIN #NumRange c CROSS JOIN #NumRange d CROSS JOIN #NumRange e WHERE a.n + (b.n * 10) + (c.n * 100) + (d.n * 1000) + (e.n * 10000) BETWEEN @MinNum AND @MaxNum ORDER BY a.n + (b.n * 10) + (c.n * 100) + (d.n * 1000) + (e.n * 10000) DROP TABLE #NumRange
-
==============================
20.이것은 단지 한 일부 응용 프로그램 테이블이 행이 같은 시퀀스 작동합니다. 내가 1..100에서 순서를한다고 가정하고, foo.bar (숫자 나 문자열 유형의) 열이있는 응용 프로그램 테이블 dbo.foo 있습니다 :
이것은 단지 한 일부 응용 프로그램 테이블이 행이 같은 시퀀스 작동합니다. 내가 1..100에서 순서를한다고 가정하고, foo.bar (숫자 나 문자열 유형의) 열이있는 응용 프로그램 테이블 dbo.foo 있습니다 :
select top 100 row_number() over (order by dbo.foo.bar) as seq from dbo.foo
ORDER BY 절에있는 그것의 존재에도 불구하고, dbo.foo.bar는 별개의 또는 null 이외의 값을 가질 필요가 없습니다.
물론, SQL 서버 2012 시퀀스 개체가 있으므로 해당 제품에 자연적인 해결책이있다.
-
==============================
21.여기에 내가 무엇을 최대 온이다 :
여기에 내가 무엇을 최대 온이다 :
create or alter function dbo.fn_range(@start int, @end int) returns table return with u2(n) as ( select n from (VALUES (0),(1),(2),(3)) v(n) ), u8(n) as ( select x0.n | x1.n * 4 | x2.n * 16 | x3.n * 64 as n from u2 x0, u2 x1, u2 x2, u2 x3 ) select @start + s.n as n from ( select x0.n | isnull(x1.n, 0) * 256 | isnull(x2.n, 0) * 65536 as n from u8 x0 left join u8 x1 on @end-@start > 256 left join u8 x2 on @end-@start > 65536 ) s where s.n < @end - @start
2 ^ 24까지의 값을 생성한다. 조건은 작은 값을 빠르게 유지하세요.
-
==============================
22.이것은 우리 DEV 서버 36 초 내 완료. 브라이언의 대답처럼, 범위 필터링에 집중하면 쿼리 내에서 중요하다 BETWEEN 여전히 그들을 필요로하지 않더라도 이전의 하한에 대한 모든 초기 레코드를 생성하려고합니다.
이것은 우리 DEV 서버 36 초 내 완료. 브라이언의 대답처럼, 범위 필터링에 집중하면 쿼리 내에서 중요하다 BETWEEN 여전히 그들을 필요로하지 않더라도 이전의 하한에 대한 모든 초기 레코드를 생성하려고합니다.
declare @s bigint = 10000000 , @e bigint = 20000000 ;WITH Z AS (SELECT 0 z FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)) T(n)), Y AS (SELECT 0 z FROM Z a, Z b, Z c, Z d, Z e, Z f, Z g, Z h, Z i, Z j, Z k, Z l, Z m, Z n, Z o, Z p), N AS (SELECT ROW_NUMBER() OVER (PARTITION BY 0 ORDER BY z) n FROM Y) SELECT TOP (1+@e-@s) @s + n - 1 FROM N
사용을하는 것이 우리가 어떤 방법으로 2 ^ 64 (== 16 ^ 16) 생성 된 기록을 통해 갈 수 있도록 참고 ROW_NUMBER는 BIGINT입니다. 이 질의는 생성 된 값에 따라서 동일한 상한을 존중한다.
-
==============================
23.이 절차 적 코드와 테이블 반환 함수를 사용합니다. 천천히,하지만 쉽게 예측.
이 절차 적 코드와 테이블 반환 함수를 사용합니다. 천천히,하지만 쉽게 예측.
CREATE FUNCTION [dbo].[Sequence] (@start int, @end int) RETURNS @Result TABLE(ID int) AS begin declare @i int; set @i = @start; while @i <= @end begin insert into @result values (@i); set @i = @i+1; end return; end
용법:
SELECT * FROM dbo.Sequence (3,7); ID 3 4 5 6 7
당신이 다른 데이터와 조인에 사용할 수 있도록 그것은 테이블입니다. A는 시간 값의 연속 순서를 보장하기 위해 시간, 일 등에 의해 그룹에 가입의 내가 가장 자주 왼쪽으로이 기능을 사용합니다.
SELECT DateAdd(hh,ID,'2018-06-20 00:00:00') as HoursInTheDay FROM dbo.Sequence (0,23) ; HoursInTheDay 2018-06-20 00:00:00.000 2018-06-20 01:00:00.000 2018-06-20 02:00:00.000 2018-06-20 03:00:00.000 2018-06-20 04:00:00.000 (...)
성능은 많은 목적을 위해 (16 만 행 초)하지만 좋은 충분히 기분이 우울합니다.
SELECT count(1) FROM [dbo].[Sequence] ( 1000001 ,2000000) GO
-
==============================
24.오라클 12C; 빠른하지만 제한 :
오라클 12C; 빠른하지만 제한 :
select rownum+1000 from all_objects fetch first 50 rows only;
참고 : ALL_OBJECTS보기의 행 수에 제한;
-
==============================
25.이것은 매우 빠르고, 유연하고 코드가 아니라 많이 있어요, 내가 할 것입니다.
이것은 매우 빠르고, 유연하고 코드가 아니라 많이 있어요, 내가 할 것입니다.
DECLARE @count int = 65536; DECLARE @start int = 11; DECLARE @xml xml = REPLICATE(CAST('<x/>' AS nvarchar(max)), @count); ; WITH GenerateNumbers(Num) AS ( SELECT ROW_NUMBER() OVER (ORDER BY @count) + @start - 1 FROM @xml.nodes('/x') X(T) ) SELECT Num FROM GenerateNumbers;
더미는 그 (@count BY ORDER)를 참고. 그것은 아무것도하지만, ROW_NUMBER ()에 의해 ORDER를 필요로하지 않습니다.
편집하다: 나는 원래의 질문이 X에서 Y의 범위를 얻을 것을 깨달았다. 내 스크립트는 범위를 얻기 위해 다음과 같이 수정할 수 있습니다 :
DECLARE @start int = 5; DECLARE @end int = 21; DECLARE @xml xml = REPLICATE(CAST('<x/>' AS nvarchar(max)), @end - @start + 1); ; WITH GenerateNumbers(Num) AS ( SELECT ROW_NUMBER() OVER (ORDER BY @end) + @start - 1 FROM @xml.nodes('/x') X(T) ) SELECT Num FROM GenerateNumbers;
-
==============================
26.내가 개발 (다른 사람의 공유 작품의 일부를 타고) 지금 꽤 많은 시간 동안 사용했습니다 솔루션은 게시 된 적어도 하나의 약간 비슷합니다. 그것은 어떤 테이블을 참조하고 1048576 개 값 (2 ^ 20)까지의 범위를 정렬되지 않은 리턴 원하는 경우 원판을 포함 할 수 없다. 필요한 경우는 물론 정렬 결과의 수 있습니다. 그것은 특히 작은 범위에 꽤 빨리 실행됩니다.
내가 개발 (다른 사람의 공유 작품의 일부를 타고) 지금 꽤 많은 시간 동안 사용했습니다 솔루션은 게시 된 적어도 하나의 약간 비슷합니다. 그것은 어떤 테이블을 참조하고 1048576 개 값 (2 ^ 20)까지의 범위를 정렬되지 않은 리턴 원하는 경우 원판을 포함 할 수 없다. 필요한 경우는 물론 정렬 결과의 수 있습니다. 그것은 특히 작은 범위에 꽤 빨리 실행됩니다.
Select value from dbo.intRange(-500, 1500) order by value -- returns 2001 values create function dbo.intRange ( @Starting as int, @Ending as int ) returns table as return ( select value from ( select @Starting + ( bit00.v | bit01.v | bit02.v | bit03.v | bit04.v | bit05.v | bit06.v | bit07.v | bit08.v | bit09.v | bit10.v | bit11.v | bit12.v | bit13.v | bit14.v | bit15.v | bit16.v | bit17.v | bit18.v | bit19.v ) as value from (select 0 as v union ALL select 0x00001 as v) as bit00 cross join (select 0 as v union ALL select 0x00002 as v) as bit01 cross join (select 0 as v union ALL select 0x00004 as v) as bit02 cross join (select 0 as v union ALL select 0x00008 as v) as bit03 cross join (select 0 as v union ALL select 0x00010 as v) as bit04 cross join (select 0 as v union ALL select 0x00020 as v) as bit05 cross join (select 0 as v union ALL select 0x00040 as v) as bit06 cross join (select 0 as v union ALL select 0x00080 as v) as bit07 cross join (select 0 as v union ALL select 0x00100 as v) as bit08 cross join (select 0 as v union ALL select 0x00200 as v) as bit09 cross join (select 0 as v union ALL select 0x00400 as v) as bit10 cross join (select 0 as v union ALL select 0x00800 as v) as bit11 cross join (select 0 as v union ALL select 0x01000 as v) as bit12 cross join (select 0 as v union ALL select 0x02000 as v) as bit13 cross join (select 0 as v union ALL select 0x04000 as v) as bit14 cross join (select 0 as v union ALL select 0x08000 as v) as bit15 cross join (select 0 as v union ALL select 0x10000 as v) as bit16 cross join (select 0 as v union ALL select 0x20000 as v) as bit17 cross join (select 0 as v union ALL select 0x40000 as v) as bit18 cross join (select 0 as v union ALL select 0x80000 as v) as bit19 ) intList where @Ending - @Starting < 0x100000 and intList.value between @Starting and @Ending )
from https://stackoverflow.com/questions/21425546/how-to-generate-a-range-of-numbers-between-two-numbers by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 이 쿼리는 쉼표로 구분 된 목록의 SQL 서버를 만들기 위해 무엇을? (0) | 2020.03.13 |
---|---|
[SQL] 어떻게 MySQL은 여러 테이블에서 삭제하려면? (0) | 2020.03.13 |
[SQL] SQL 서버 - 저장 프로 시저에서 SELECT (0) | 2020.03.13 |
[SQL] SQL - 그룹에 의해 별칭을 사용 (0) | 2020.03.13 |
[SQL] 어떻게 엔티티 프레임 워크를 사용하여 하나 개의 필드를 업데이트하는? (0) | 2020.03.13 |