[SQL] SQL의 모든 조합을 생성
SQLSQL의 모든 조합을 생성
나는 크기 @n의 주어진 집합의 크기 @k의 모든 조합을 생성해야합니다. 누군가가 다음과 같은 SQL을 검토하고 다음과 같은 논리가 예상되는 결과를 반환하는 경우 먼저 결정하고, 두 번째 더 좋은 방법이 있다면시겠습니까?
/*CREATE FUNCTION dbo.Factorial ( @x int )
RETURNS int
AS
BEGIN
DECLARE @value int
IF @x <= 1
SET @value = 1
ELSE
SET @value = @x * dbo.Factorial( @x - 1 )
RETURN @value
END
GO*/
SET NOCOUNT ON;
DECLARE @k int = 5, @n int;
DECLARE @set table ( [value] varchar(24) );
DECLARE @com table ( [index] int );
INSERT @set VALUES ('1'),('2'),('3'),('4'),('5'),('6');
SELECT @n = COUNT(*) FROM @set;
DECLARE @combinations int = dbo.Factorial(@n) / (dbo.Factorial(@k) * dbo.Factorial(@n - @k));
PRINT CAST(@combinations as varchar(max)) + ' combinations';
DECLARE @index int = 1;
WHILE @index <= @combinations
BEGIN
INSERT @com VALUES (@index)
SET @index = @index + 1
END;
WITH [set] as (
SELECT
[value],
ROW_NUMBER() OVER ( ORDER BY [value] ) as [index]
FROM @set
)
SELECT
[values].[value],
[index].[index] as [combination]
FROM [set] [values]
CROSS JOIN @com [index]
WHERE ([index].[index] + [values].[index] - 1) % (@n) BETWEEN 1 AND @k
ORDER BY
[index].[index];
해결법
-
==============================
1.번호 테이블을 사용하거나 다수 발생 CTE를 0, 2 ^ N을 선택 - 조합의 상대 부재의 유무를 나타 내기 위해 이러한 수치에 1 초를 포함하는 비트 위치를 사용하여 (1), 및 이들을 제거하는 것은하지 않아도 값의 정확한 수는, 당신은 당신이 원하는 모든 조합 결과 집합을 반환 할 수 있어야한다.
번호 테이블을 사용하거나 다수 발생 CTE를 0, 2 ^ N을 선택 - 조합의 상대 부재의 유무를 나타 내기 위해 이러한 수치에 1 초를 포함하는 비트 위치를 사용하여 (1), 및 이들을 제거하는 것은하지 않아도 값의 정확한 수는, 당신은 당신이 원하는 모든 조합 결과 집합을 반환 할 수 있어야한다.
WITH Nums (Num) AS ( SELECT Num FROM Numbers WHERE Num BETWEEN 0 AND POWER(2, @n) - 1 ), BaseSet AS ( SELECT ind = Power(2, Row_Number() OVER (ORDER BY Value) - 1), * FROM @set ), Combos AS ( SELECT ComboID = N.Num, S.Value, Cnt = Count(*) OVER (PARTITION BY N.Num) FROM Nums N INNER JOIN BaseSet S ON N.Num & S.ind <> 0 ) SELECT ComboID, Value FROM Combos WHERE Cnt = @k ORDER BY ComboID, Value;
이 쿼리의 수행은 꽤 잘하지만, 내가 먼저 한 번에 촬영 한 항목의 오른쪽 숫자를 얻기 위해 맵시 병렬 비트 카운트에서 cribbing,이를 최적화 할 수있는 방법을 생각했다. 이 빠르게 수행 3-3.5 시간 (CPU와 시간) :
WITH Nums AS ( SELECT Num, P1 = (Num & 0x55555555) + ((Num / 2) & 0x55555555) FROM dbo.Numbers WHERE Num BETWEEN 0 AND POWER(2, @n) - 1 ), Nums2 AS ( SELECT Num, P2 = (P1 & 0x33333333) + ((P1 / 4) & 0x33333333) FROM Nums ), Nums3 AS ( SELECT Num, P3 = (P2 & 0x0f0f0f0f) + ((P2 / 16) & 0x0f0f0f0f) FROM Nums2 ), BaseSet AS ( SELECT ind = Power(2, Row_Number() OVER (ORDER BY Value) - 1), * FROM @set ) SELECT ComboID = N.Num, S.Value FROM Nums3 N INNER JOIN BaseSet S ON N.Num & S.ind <> 0 WHERE P3 % 255 = @k ORDER BY ComboID, Value;
내가 가서 비트 계산 페이지를 읽고 난 % (255)을하지만, 비트 연산 모든 길을 갈하지 않으려면이 더 잘 수행 할 수 있다고 생각합니다. 내가 기회를 얻을 때 나는 그것을 시도 할 것이다 그것은 최대 스택 방법을 참조하십시오.
내 성능 주장은 ORDER BY 절없이 실행 쿼리를 기반으로합니다. 명확성을 위해, 어떤 코드 일 것은 번호 테이블에서 민 설정 한 비트 수를 카운트한다. 숫자 세트의 요소가 현재 결합되어있는 선택 인덱서의 일종으로 사용하고 있기 때문에 1 비트 수와 동일한 수 있도록 즉,이다.
나는 그것을 좋아하면 좋겠!
기록을 위해, 세트의 멤버를 선택하는 정수의 비트 패턴을 사용하는이 기술은 제가 만들어 낸 한 것입니다 "수직 크로스에 가입하세요." 효과적으로 상호의 결과 세트 및 교차 결합의 수는 임의의 데이터의 다수의 세트, 조인. 여기에, 세트 수는 한 번에 촬영 한 항목의 수입니다.
사실이 같은 것을 보일 것이다 (각 가입에 열 기존 목록에 더 많은 열을 추가하는) 일반적인 수평 의미에서 합류 교차 :
SELECT A.Value, B.Value, C.Value FROM @Set A CROSS JOIN @Set B CROSS JOIN @Set C WHERE A.Value = 'A' AND B.Value = 'B' AND C.Value = 'C'
내 쿼리는 위 효과적으로 결합 하나에 필요한만큼 여러 번 "크로스 조인". 결과는 물론, 조인 실제 십자가에 비해 피봇 팅, 그러나 그것은 사소한 사항입니다.
첫째, 나는 당신의 계승 UDF이 변경을 제안 할 수 있습니다 :
ALTER FUNCTION dbo.Factorial ( @x bigint ) RETURNS bigint AS BEGIN IF @x <= 1 RETURN 1 RETURN @x * dbo.Factorial(@x - 1) END
지금 당신은 조합의 더 큰 세트를 계산할 수, 플러스 것이 더 효율적입니다. 당신은 당신의 조합 계산에 더 큰 중간 계산을 할 수 있도록 진수 (38, 0)를 사용하는 것이 좋습니다.
둘째, 당신의 주어진 쿼리는 올바른 결과를 반환하지 않습니다. 예를 들어, 아래 테스트 성능에서 내 테스트 데이터를 사용하여, 세트 1 세트 쿼리 주위에 래핑하는 슬라이딩 스트라이프 걸리는 것 같습니다 (18)과 동일 : 각 세트 이런 식으로 뭔가를 찾고, 항상 5 개 인접한 회원입니다 (나는 선회 ) 쉽게 볼 수 있도록합니다 :
1 ABCDE 2 ABCD Q 3 ABC PQ 4 AB OPQ 5 A NOPQ 6 MNOPQ 7 LMNOP 8 KLMNO 9 JKLMN 10 IJKLM 11 HIJKL 12 GHIJK 13 FGHIJ 14 EFGHI 15 DEFGH 16 CDEFG 17 BCDEF 18 ABCDE 19 ABCD Q
패턴을 내 쿼리에서 비교 :
31 ABCDE 47 ABCD F 55 ABC EF 59 AB DEF 61 A CDEF 62 BCDEF 79 ABCD G 87 ABC E G 91 AB DE G 93 A CDE G 94 BCDE G 103 ABC FG 107 AB D FG 109 A CD FG 110 BCD FG 115 AB EFG 117 A C EFG 118 BC EFG 121 A DEFG ...
그냥 비트 패턴을 구동하기 -> 진 = 11111에서 아무도 관심을 통지 그 (31)에 대한 조합의 일이 가정의 인덱스와 패턴 ABCDE이다. 이진수 121 1,111,001이고 패턴 A__DEFG이다 (거꾸로 매핑).
나는 위의 내 두 번째 쿼리에 큰 세트와 테스트 어떤 성능을 달렸다. 내가 사용하는 서버 버전의이 시간에 대한 기록이 없습니다. 여기 내 테스트 데이터는 다음과 같습니다
DECLARE @k int, @n int; DECLARE @set TABLE (value varchar(24)); INSERT @set VALUES ('A'),('B'),('C'),('D'),('E'),('F'),('G'),('H'),('I'),('J'),('K'),('L'),('M'),('N'),('O'),('P'),('Q'); SET @n = @@RowCount; SET @k = 5; DECLARE @combinations bigint = dbo.Factorial(@n) / (dbo.Factorial(@k) * dbo.Factorial(@n - @k)); SELECT CAST(@combinations as varchar(max)) + ' combinations', MaxNumUsedFromNumbersTable = POWER(2, @n);
베드로는이 "수직 교차 조인"실제로 CROSS 그것을 방지 조인 할 수있는 동적 SQL을 작성뿐만 아니라 간단하게 수행하지 않는 것으로 나타났다. 몇의 사소한 비용 읽기에서 자신의 솔루션은 10 개 17 배 더 나은 사이의 측정이있다. 자신의 쿼리의 성능은 빠르게 나보다 작업의 양이 증가로 감소하지만 충분히 빨리 그것을 사용하는 사람을 중지 할 수 있습니다.
숫자의 두 번째 세트는 아래 그냥 확장 방법을 보여 테이블의 첫 번째 행으로 나눈 값으로 요인이다.
에릭
Items CPU Writes Reads Duration | CPU Writes Reads Duration ----- ------ ------ ------- -------- | ----- ------ ------ -------- 17•5 7344 0 3861 8531 | 18•9 17141 0 7748 18536 | 2.3 2.0 2.2 20•10 76657 0 34078 84614 | 10.4 8.8 9.9 21•11 163859 0 73426 176969 | 22.3 19.0 20.7 21•20 142172 0 71198 154441 | 19.4 18.4 18.1
베드로
Items CPU Writes Reads Duration | CPU Writes Reads Duration ----- ------ ------ ------- -------- | ----- ------ ------ -------- 17•5 422 70 10263 794 | 18•9 6046 980 219180 11148 | 14.3 14.0 21.4 14.0 20•10 24422 4126 901172 46106 | 57.9 58.9 87.8 58.1 21•11 58266 8560 2295116 104210 | 138.1 122.3 223.6 131.3 21•20 51391 5 6291273 55169 | 121.8 0.1 613.0 69.5
(이것은 읽기의 시작부터 비록) 외삽, 결국 내 쿼리는 아니지만 오랫동안 저렴 될 것입니다. 세트에서 21 개 항목을 사용하려면 이미 2097152까지가는 숫자 테이블을 필요로 ...
여기에 내가 원래 내 솔루션은 온 - 더 - 플라이 번호 테이블과 크게 더 나은 수행하는 것을 실현하기 전에 만든 주석입니다 :
나는 원래이 답을 썼을 때, 나는 말했다 :
글쎄, 난 그것을 시도, 그 결과는 매우 잘 수행하는 것이 있었다! 여기 내가 사용하는 쿼리는 다음과 같습니다
DECLARE @N int = 16, @K int = 12; CREATE TABLE #Set (Value char(1) PRIMARY KEY CLUSTERED); CREATE TABLE #Items (Num int); INSERT #Items VALUES (@K); INSERT #Set SELECT TOP (@N) V FROM (VALUES ('A'),('B'),('C'),('D'),('E'),('F'),('G'),('H'),('I'),('J'),('K'),('L'),('M'),('N'),('O'),('P'),('Q'),('R'),('S'),('T'),('U'),('V'),('W'),('X'),('Y'),('Z')) X (V); GO DECLARE @N int = (SELECT Count(*) FROM #Set), @K int = (SELECT TOP 1 Num FROM #Items); DECLARE @combination int, @value char(1); WITH L0 AS (SELECT 1 N UNION ALL SELECT 1), L1 AS (SELECT 1 N FROM L0, L0 B), L2 AS (SELECT 1 N FROM L1, L1 B), L3 AS (SELECT 1 N FROM L2, L2 B), L4 AS (SELECT 1 N FROM L3, L3 B), L5 AS (SELECT 1 N FROM L4, L4 B), Nums AS (SELECT Row_Number() OVER(ORDER BY (SELECT 1)) Num FROM L5), Nums1 AS ( SELECT Num, P1 = (Num & 0x55555555) + ((Num / 2) & 0x55555555) FROM Nums WHERE Num BETWEEN 0 AND Power(2, @N) - 1 ), Nums2 AS ( SELECT Num, P2 = (P1 & 0x33333333) + ((P1 / 4) & 0x33333333) FROM Nums1 ), Nums3 AS ( SELECT Num, P3 = (P2 & 0x0F0F0F0F) + ((P2 / 16) & 0x0F0F0F0F) FROM Nums2 ), BaseSet AS ( SELECT Ind = Power(2, Row_Number() OVER (ORDER BY Value) - 1), * FROM #Set ) SELECT @Combination = N.Num, @Value = S.Value FROM Nums3 N INNER JOIN BaseSet S ON N.Num & S.Ind <> 0 WHERE P3 % 255 = @K;
내가 변수에 값을 선택했는지 참고 시험 모두에 필요한 시간과 메모리를 줄일 수 있습니다. 서버는 여전히 동일한 작업을 수행합니다. 나는 유사한 것으로 베드로의 버전을 수정하고 가능한 한 린으로 모두를했다, 그래서 불필요한 엑스트라를 제거했습니다. (VM)을 VM에서 실행 : 윈도우 NT 5.2 <86> (서비스 팩 2 빌드 3790)에 10.0.1600.22 (인텔 X86) 스탠다드 에디션 -이 테스트에 사용 된 서버 버전은 마이크로 소프트 SQL 서버 2008 (RTM)입니다.
그 다음의 기본 데이터는 해당 페이지의 다른 답에 21까지 N과 K의 값의 성능 곡선을 나타내는 그래프이다. 값은 각 메트릭에 대한 가장 최악 값을 던지고, 나머지 3 평균이어서 각각 K 및 N 값에 각각 5 개 쿼리 실행의 결과이다.
기본적으로, 내 버전은 동적의 SQL 버전보다 더이 수행 할 수 있도록 N의 높은 가치와 K의 낮은 값에서 (차트의 왼쪽 모서리에있는)는 "어깨"를 가지고있다. 그러나,이 체류 비교적 낮은 일정하고 매우 시간, CPU 낮다 N = 21, K = 11 주변의 중앙 피크와는 동적 SQL 버전보다 읽는다.
나는 각 항목은 당신이 얼마나 큰 일에 쌓아 쿼리가 수행하는 방법을 볼 수 있도록 반환 할 것으로 예상된다 행의 수의 도표를 포함.
전체 성능 결과를이 페이지에 내 추가 대답을 참조하십시오. 나는 포스트 자 제한을 명중하고 여기에 포함되지 수 있습니다. (? 어떤 아이디어가 다른 어디 넣어) 내 첫 번째 버전의 성능 결과에 대한 관점에 물건을 넣으려면, 여기에 이전과 같은 형식이다 :
에릭
Items CPU Duration Reads Writes | CPU Duration Reads ----- ----- -------- ------- ------ | ----- -------- ------- 17•5 354 378 12382 0 | 18•9 1849 1893 97246 0 | 5.2 5.0 7.9 20•10 7119 7357 369518 0 | 20.1 19.5 29.8 21•11 13531 13807 705438 0 | 38.2 36.5 57.0 21•20 3234 3295 48 0 | 9.1 8.7 0.0
베드로
Items CPU Duration Reads Writes | CPU Duration Reads ----- ----- -------- ------- ------ | ----- -------- ------- 17•5 41 45 6433 0 | 18•9 2051 1522 214021 0 | 50.0 33.8 33.3 20•10 8271 6685 864455 0 | 201.7 148.6 134.4 21•11 18823 15502 2097909 0 | 459.1 344.5 326.1 21•20 25688 17653 4195863 0 | 626.5 392.3 652.2
기간 분석
분석을 읽
기간 분석은 내 쿼리가 중요하지만 지나치게 크지 않은 금액으로 승리했다. 메트릭을 읽고로 전환 될 때, 매우 다른 그림이 나온다 - (가) 읽기 평균 1 / 10 일 내 쿼리 사용합니다.
나는 업데이트 된 동적 SQL 버전의 결과를보고 매우 관심이있을 것이라고 풋 내가 전술 한 바와 같이 각 단계에서 선택된 항목에 대한 여분의 상한.
내 쿼리의 다음 버전은 위의 실적 결과를 통해 2.25에 대한 %의 향상을 달성 할 수있다. 나는 MIT의 HAKMEM 비트 계산 방법을 사용하고, ROW_NUMBER () 그것은 BIGINT를 반환 이후의 결과에 변환 (int)를 추가했다. 물론 나는이 내가 성능 테스트 및 차트와 위의 데이터 모두를 위해 사용했던 버전입니다 좋겠지 만, 노동 집약적했다으로 내가 그것을 다시 실행됩니다 않을 수 있습니다.
WITH L0 AS (SELECT 1 N UNION ALL SELECT 1), L1 AS (SELECT 1 N FROM L0, L0 B), L2 AS (SELECT 1 N FROM L1, L1 B), L3 AS (SELECT 1 N FROM L2, L2 B), L4 AS (SELECT 1 N FROM L3, L3 B), L5 AS (SELECT 1 N FROM L4, L4 B), Nums AS (SELECT Row_Number() OVER(ORDER BY (SELECT 1)) Num FROM L5), Nums1 AS ( SELECT Convert(int, Num) Num FROM Nums WHERE Num BETWEEN 1 AND Power(2, @N) - 1 ), Nums2 AS ( SELECT Num, P1 = Num - ((Num / 2) & 0xDB6DB6DB) - ((Num / 4) & 0x49249249) FROM Nums1 ), Nums3 AS (SELECT Num, Bits = ((P1 + P1 / 8) & 0xC71C71C7) % 63 FROM Nums2), BaseSet AS (SELECT Ind = Power(2, Row_Number() OVER (ORDER BY Value) - 1), * FROM #Set) SELECT N.Num, S.Value FROM Nums3 N INNER JOIN BaseSet S ON N.Num & S.Ind <> 0 WHERE Bits = @K
그리고 비트의 수를 얻기 위해 조회를 수행 또 하나의 버전을 표시 저항 할 수 없었다. 그것은 더 빨리 다른 버전보다 수 있습니다 :
DECLARE @BitCounts binary(255) = 0x01010201020203010202030203030401020203020303040203030403040405 + 0x0102020302030304020303040304040502030304030404050304040504050506 + 0x0102020302030304020303040304040502030304030404050304040504050506 + 0x0203030403040405030404050405050603040405040505060405050605060607 + 0x0102020302030304020303040304040502030304030404050304040504050506 + 0x0203030403040405030404050405050603040405040505060405050605060607 + 0x0203030403040405030404050405050603040405040505060405050605060607 + 0x0304040504050506040505060506060704050506050606070506060706070708; WITH L0 AS (SELECT 1 N UNION ALL SELECT 1), L1 AS (SELECT 1 N FROM L0, L0 B), L2 AS (SELECT 1 N FROM L1, L1 B), L3 AS (SELECT 1 N FROM L2, L2 B), L4 AS (SELECT 1 N FROM L3, L3 B), L5 AS (SELECT 1 N FROM L4, L4 B), Nums AS (SELECT Row_Number() OVER(ORDER BY (SELECT 1)) Num FROM L5), Nums1 AS (SELECT Convert(int, Num) Num FROM Nums WHERE Num BETWEEN 1 AND Power(2, @N) - 1), BaseSet AS (SELECT Ind = Power(2, Row_Number() OVER (ORDER BY Value) - 1), * FROM ComboSet) SELECT @Combination = N.Num, @Value = S.Value FROM Nums1 N INNER JOIN BaseSet S ON N.Num & S.Ind <> 0 WHERE @K = Convert(int, Substring(@BitCounts, N.Num & 0xFF, 1)) + Convert(int, Substring(@BitCounts, N.Num / 256 & 0xFF, 1)) + Convert(int, Substring(@BitCounts, N.Num / 65536 & 0xFF, 1)) + Convert(int, Substring(@BitCounts, N.Num / 16777216, 1))
-
==============================
2.이 여분의 답을 용서하십시오. 나는 내 원래의 대답 후 문자 제한에 달렸다.
이 여분의 답을 용서하십시오. 나는 내 원래의 대답 후 문자 제한에 달렸다.
여기에 내 대답에 차트의 전체 평균 수치 성능 결과입니다.
| Erik | Peter N K | CPU Duration Reads Writes | CPU Duration Reads Writes -- -- - ----- -------- ------ ------ - ----- -------- ------- ------ 1 1 | 0 0 7 0 | 0 0 7 0 2 1 | 0 0 10 0 | 0 0 7 0 2 2 | 0 0 7 0 | 0 0 11 0 3 1 | 0 0 12 0 | 0 0 7 0 3 2 | 0 0 12 0 | 0 0 13 0 3 3 | 5 0 7 0 | 0 0 19 0 4 1 | 0 0 14 0 | 0 0 7 0 4 2 | 0 0 18 0 | 0 0 15 0 4 3 | 0 0 14 0 | 5 0 27 0 4 4 | 0 0 7 0 | 0 0 35 0 5 1 | 5 0 16 0 | 5 0 7 0 5 2 | 0 0 26 0 | 0 0 17 0 5 3 | 0 0 26 0 | 0 0 37 0 5 4 | 0 0 16 0 | 0 0 57 0 5 5 | 0 0 7 0 | 0 0 67 0 6 1 | 0 0 18 0 | 0 0 7 0 6 2 | 5 0 36 0 | 0 0 19 0 6 3 | 0 0 46 0 | 0 0 49 0 6 4 | 0 0 36 0 | 0 0 89 0 6 5 | 5 0 18 0 | 5 0 119 0 6 6 | 0 0 7 0 | 0 0 131 0 7 1 | 5 0 20 0 | 0 0 7 0 7 2 | 0 0 48 0 | 0 0 21 0 7 3 | 0 0 76 0 | 0 0 63 0 7 4 | 0 0 76 0 | 0 0 133 0 7 5 | 0 1 48 0 | 0 1 203 0 7 6 | 5 0 20 0 | 0 1 245 0 7 7 | 5 0 7 0 | 0 3 259 0 8 1 | 5 2 22 0 | 0 4 7 0 8 2 | 0 1 62 0 | 0 0 23 0 8 3 | 0 1 118 0 | 0 0 79 0 8 4 | 0 1 146 0 | 0 1 191 0 8 5 | 5 3 118 0 | 0 1 331 0 8 6 | 5 1 62 0 | 5 2 443 0 8 7 | 0 0 22 0 | 5 3 499 0 8 8 | 0 0 7 0 | 5 3 515 0 9 1 | 0 2 24 0 | 0 0 7 0 9 2 | 5 3 78 0 | 0 0 25 0 9 3 | 5 3 174 0 | 0 1 97 0 9 4 | 5 5 258 0 | 0 2 265 0 9 5 | 5 7 258 0 | 10 4 517 0 9 6 | 5 5 174 0 | 5 5 769 0 9 7 | 0 3 78 0 | 10 4 937 0 9 8 | 0 0 24 0 | 0 3 1009 0 9 9 | 0 1 7 0 | 0 4 1027 0 10 1 | 10 4 26 0 | 0 0 7 0 10 2 | 5 5 96 0 | 0 0 27 0 10 3 | 5 2 246 0 | 0 0 117 0 10 4 | 10 10 426 0 | 10 4 357 0 10 5 | 15 12 510 0 | 5 8 777 0 10 6 | 15 16 426 0 | 10 9 1281 0 10 7 | 10 4 246 0 | 10 9 1701 0 10 8 | 10 5 96 0 | 10 5 1941 0 10 9 | 5 4 26 0 | 10 7 2031 0 10 10 | 5 0 7 0 | 10 7 2051 0 11 1 | 10 8 28 0 | 0 0 7 0 11 2 | 15 11 116 0 | 0 0 29 0 11 3 | 21 24 336 0 | 10 3 139 0 11 4 | 21 18 666 0 | 5 2 469 0 11 5 | 21 20 930 0 | 5 3 1129 0 11 6 | 26 35 930 0 | 15 12 2053 0 11 7 | 20 14 666 0 | 5 25 2977 0 11 8 | 15 9 336 0 | 20 14 3637 0 11 9 | 10 7 116 0 | 21 27 3967 0 11 10 | 10 8 28 0 | 36 34 4086 0 11 11 | 5 8 7 0 | 15 15 4109 0 12 1 | 16 18 30 0 | 5 0 7 0 12 2 | 31 32 138 0 | 0 0 31 0 12 3 | 31 26 446 0 | 10 2 163 0 12 4 | 47 40 996 0 | 10 7 603 0 12 5 | 47 46 1590 0 | 21 17 1593 0 12 6 | 57 53 1854 0 | 31 30 3177 0 12 7 | 41 39 1590 0 | 31 30 5025 0 12 8 | 41 42 996 0 | 42 43 6609 0 12 9 | 31 26 446 0 | 52 52 7607 0 12 10 | 20 19 138 0 | 57 62 8048 0 12 11 | 15 17 30 0 | 72 64 8181 0 12 12 | 15 10 7 0 | 67 38 8217 0 13 1 | 31 32 32 0 | 0 0 7 0 13 2 | 21 25 162 0 | 0 0 33 0 13 3 | 36 34 578 0 | 5 2 189 0 13 4 | 57 65 1436 0 | 10 5 761 0 13 5 | 41 40 2580 0 | 10 10 2191 0 13 6 | 62 56 3438 0 | 31 32 4765 0 13 7 | 62 62 3438 0 | 57 53 8251 0 13 8 | 52 64 2580 0 | 52 47 11710 0 13 9 | 26 28 1436 0 | 93 96 14311 0 13 10 | 31 29 578 0 | 161 104 15891 0 13 11 | 36 35 162 0 | 129 99 16525 0 13 12 | 21 22 32 0 | 156 96 16383 0 13 13 | 26 30 7 0 | 166 98 16411 0 14 1 | 57 53 34 0 | 0 0 7 0 14 2 | 52 50 188 0 | 0 0 35 0 14 3 | 57 60 734 0 | 10 4 217 0 14 4 | 78 76 2008 0 | 15 8 945 0 14 5 | 99 97 4010 0 | 36 34 2947 0 14 6 | 120 125 6012 0 | 41 47 6951 0 14 7 | 125 119 6870 0 | 93 94 12957 0 14 8 | 135 138 6012 0 | 88 98 19821 0 14 9 | 78 153 4010 0 | 234 156 26099 0 14 10 | 94 92 2008 0 | 229 133 30169 0 14 11 | 83 90 734 0 | 239 136 32237 0 14 12 | 47 46 188 0 | 281 176 33031 0 14 13 | 52 53 34 0 | 260 167 32767 0 14 14 | 46 47 7 0 | 203 149 32797 0 15 1 | 83 83 36 0 | 0 0 7 0 15 2 | 145 139 216 0 | 0 2 37 0 15 3 | 104 98 916 0 | 0 2 247 0 15 4 | 135 135 2736 0 | 15 17 1157 0 15 5 | 94 97 6012 0 | 26 27 3887 0 15 6 | 192 188 10016 0 | 57 53 9893 0 15 7 | 187 192 12876 0 | 73 73 19903 0 15 8 | 286 296 12876 0 | 338 230 33123 0 15 9 | 208 207 10016 0 | 354 223 46063 0 15 10 | 140 143 6012 0 | 443 334 56143 0 15 11 | 88 86 2736 0 | 391 273 62219 0 15 12 | 73 72 916 0 | 432 269 65019 0 15 13 | 109 117 216 0 | 317 210 65999 0 15 14 | 156 187 36 0 | 411 277 66279 0 15 15 | 140 142 7 0 | 354 209 65567 0 16 1 | 281 281 38 0 | 0 0 7 0 16 2 | 141 146 246 0 | 0 0 39 0 16 3 | 208 206 1126 0 | 10 4 279 0 16 4 | 187 189 3646 0 | 15 13 1399 0 16 5 | 234 234 8742 0 | 42 42 5039 0 16 6 | 333 337 16022 0 | 83 85 13775 0 16 7 | 672 742 22886 0 | 395 235 30087 0 16 8 | 510 510 25746 0 | 479 305 53041 0 16 9 | 672 675 22886 0 | 671 489 78855 0 16 10 | 489 492 16022 0 | 859 578 101809 0 16 11 | 250 258 8742 0 | 719 487 117899 0 16 12 | 198 202 3646 0 | 745 483 126709 0 16 13 | 119 119 1126 0 | 770 506 130423 0 16 14 | 291 327 246 0 | 770 531 131617 0 16 15 | 156 156 38 0 | 713 451 131931 0 16 16 | 125 139 7 0 | 895 631 132037 0 17 1 | 406 437 40 0 | 0 0 7 0 17 2 | 307 320 278 0 | 0 0 41 0 17 3 | 281 290 1366 0 | 0 3 313 0 17 4 | 307 317 4766 0 | 31 28 1673 0 17 5 | 354 378 12382 0 | 41 45 6433 0 17 6 | 583 582 24758 0 | 130 127 18809 0 17 7 | 839 859 38902 0 | 693 449 43873 0 17 8 | 1177 1183 48626 0 | 916 679 82847 0 17 9 | 1031 1054 48626 0 | 1270 944 131545 0 17 10 | 828 832 38902 0 | 1469 1105 180243 0 17 11 | 672 668 24758 0 | 1535 1114 219217 0 17 12 | 422 422 12382 0 | 1494 991 244047 0 17 13 | 474 482 4766 0 | 1615 1165 256501 0 17 14 | 599 607 1366 0 | 1500 1042 261339 0 17 15 | 223 218 278 0 | 1401 1065 262777 0 17 16 | 229 228 40 0 | 1390 918 263127 0 17 17 | 541 554 7 0 | 1562 1045 263239 0 18 1 | 401 405 42 0 | 0 0 7 0 18 2 | 401 397 312 0 | 0 0 43 0 18 3 | 458 493 1638 0 | 5 6 349 0 18 4 | 583 581 6126 0 | 16 13 1981 0 18 5 | 697 700 17142 0 | 83 130 8101 0 18 6 | 792 799 37134 0 | 156 162 25237 0 18 7 | 1672 1727 63654 0 | 1098 751 62693 0 18 8 | 1598 1601 87522 0 | 1416 1007 126423 0 18 9 | 1849 1893 97246 0 | 2051 1522 214021 0 18 10 | 1963 2083 87522 0 | 2734 2103 311343 0 18 11 | 1411 1428 63654 0 | 2849 2352 398941 0 18 12 | 1042 1048 37134 0 | 3021 2332 462671 0 18 13 | 942 985 17142 0 | 3036 2314 499881 0 18 14 | 656 666 6126 0 | 3052 2177 517099 0 18 15 | 526 532 1638 0 | 2910 2021 523301 0 18 16 | 614 621 312 0 | 3083 2108 525015 0 18 17 | 536 551 42 0 | 2921 2031 525403 0 18 18 | 682 680 7 0 | 3141 2098 525521 0 19 1 | 885 909 44 0 | 0 0 7 0 19 2 | 1411 1498 348 0 | 0 0 45 0 19 3 | 880 887 1944 0 | 5 4 387 0 19 4 | 1119 1139 7758 0 | 26 25 2325 0 19 5 | 1120 1127 23262 0 | 73 72 10077 0 19 6 | 1395 1462 54270 0 | 453 387 33591 0 19 7 | 1875 1929 100782 0 | 1197 838 87941 0 19 8 | 2656 2723 151170 0 | 2255 1616 188803 0 19 9 | 3046 3092 184762 0 | 3317 2568 340053 0 19 10 | 3635 3803 184762 0 | 5171 4041 524895 0 19 11 | 2739 2774 151170 0 | 5577 4574 709737 0 19 12 | 3203 3348 100782 0 | 6182 5194 860987 0 19 13 | 1672 1750 54270 0 | 6458 5561 961849 0 19 14 | 1760 1835 23262 0 | 6177 4964 1016199 0 19 15 | 968 1006 7758 0 | 6266 4331 1039541 0 19 16 | 1099 1134 1944 0 | 6208 4254 1047379 0 19 17 | 995 1037 348 0 | 6385 4366 1049403 0 19 18 | 916 964 44 0 | 6036 4268 1049831 0 19 19 | 1135 1138 7 0 | 6234 4320 1049955 0 20 1 | 1797 1821 46 0 | 0 0 7 0 20 2 | 2000 2029 386 0 | 0 0 47 0 20 3 | 2031 2071 2286 0 | 10 6 427 0 20 4 | 1942 2036 9696 0 | 31 34 2707 0 20 5 | 2104 2161 31014 0 | 88 85 12397 0 20 6 | 2880 2958 77526 0 | 860 554 43675 0 20 7 | 3791 3940 155046 0 | 2026 1405 121285 0 20 8 | 5130 5307 251946 0 | 3823 2731 276415 0 20 9 | 6547 6845 335926 0 | 5380 4148 528445 0 20 10 | 7119 7357 369518 0 | 8271 6685 864455 0 20 11 | 5692 5803 335926 0 | 9557 8029 1234057 0 20 12 | 4734 4850 251946 0 | 11114 9504 1570067 0 20 13 | 3604 3641 155046 0 | 11551 10434 1822097 0 20 14 | 2911 2999 77526 0 | 12317 10822 1977227 0 20 15 | 2115 2134 31014 0 | 12806 10679 2054837 0 20 16 | 2041 2095 9696 0 | 13062 9115 2085935 0 20 17 | 2390 2465 2286 0 | 12807 9002 2095715 0 20 18 | 1765 1788 386 0 | 12598 8601 2098085 0 20 19 | 2067 2143 46 0 | 12578 8626 2098555 0 20 20 | 1640 1663 7 0 | 12932 9064 2098685 0 21 1 | 3374 3425 48 0 | 0 0 7 0 21 2 | 4031 4157 426 0 | 0 1 49 0 21 3 | 3218 3250 2666 0 | 10 5 469 0 21 4 | 3687 3734 11976 0 | 21 25 3129 0 21 5 | 3692 3735 40704 0 | 115 114 15099 0 21 6 | 4859 4943 108534 0 | 963 661 56079 0 21 7 | 6114 6218 232566 0 | 2620 1880 164701 0 21 8 | 8573 8745 406986 0 | 4999 3693 397355 0 21 9 | 11880 12186 587866 0 | 9047 6863 804429 0 21 10 | 13255 13582 705438 0 | 14358 11436 1392383 0 21 11 | 13531 13807 705438 0 | 18823 15502 2097909 0 21 12 | 12244 12400 587866 0 | 21834 18760 2803435 0 21 13 | 9406 9528 406986 0 | 23771 21274 3391389 0 21 14 | 7114 7180 232566 0 | 26677 24296 3798463 0 21 15 | 4869 4961 108534 0 | 26479 23998 4031117 0 21 16 | 4416 4521 40704 0 | 26536 22976 4139739 0 21 17 | 4380 4443 11976 0 | 26490 19107 4180531 0 21 18 | 3265 3334 2666 0 | 25979 17995 4192595 0 21 19 | 3640 3768 426 0 | 26186 17891 4195349 0 21 20 | 3234 3295 48 0 | 25688 17653 4195863 0 21 21 | 3156 3219 7 0 | 26140 17838 4195999 0
-
==============================
3.어떻게 일부 동적 SQL에 대한?
어떻게 일부 동적 SQL에 대한?
DECLARE @k int = 5, @n INT IF OBJECT_ID('tempdb..#set') IS NOT NULL DROP TABLE #set CREATE TABLE #set ( [value] varchar(24) ) INSERT #set VALUES ('1'),('2'),('3'),('4'),('5'),('6') SET @n = @@ROWCOUNT SELECT dbo.Factorial(@n) / (dbo.Factorial(@k) * dbo.Factorial(@n - @k)) AS [expected combinations] -- let's generate some sql. DECLARE @crlf NCHAR(2) = NCHAR(13)+NCHAR(10) , @sql NVARCHAR(MAX) , @select NVARCHAR(MAX) , @from NVARCHAR(MAX) , @order NVARCHAR(MAX) , @in NVARCHAR(MAX) DECLARE @j INT = 0 WHILE @j < @k BEGIN SET @j += 1 IF @j = 1 BEGIN SET @select = 'SELECT'+@crlf+' _1.value AS [1]' SET @from = @crlf+'FROM #set AS _1' SET @order = 'ORDER BY _1.value' SET @in = '[1]' END ELSE BEGIN SET @select += @crlf+', _'+CONVERT(VARCHAR,@j)+'.value AS ['+CONVERT(VARCHAR,@j)+']' SET @from += @crlf+'INNER JOIN #set AS _'+CONVERT(VARCHAR,@j)+' ON _'+CONVERT(VARCHAR,@j)+'.value > _'+CONVERT(VARCHAR,@j-1)+'.value' SET @order += ', _'+CONVERT(VARCHAR,@j)+'.value' SET @in += ', ['+CONVERT(VARCHAR,@j)+']' END END SET @select += @crlf+', ROW_NUMBER() OVER ('+@order+') AS combination' SET @sql = @select + @from -- let's see how it looks PRINT @sql EXEC (@sql) -- ok, now dump pivot and dump into a table for later use IF OBJECT_ID('tempdb..#combinations') IS NOT NULL DROP TABLE #combinations CREATE TABLE #combinations ( combination INT , value VARCHAR(24) , PRIMARY KEY (combination, value) ) SET @sql = 'WITH CTE AS ('+@crlf+@sql+@crlf+')'+@crlf + 'INSERT #combinations (combination, value)'+@crlf + 'SELECT combination, value FROM CTE a'+@crlf + 'UNPIVOT (value FOR position IN ('+@in+')) AS b' PRINT @sql EXEC (@sql) SELECT COUNT(DISTINCT combination) AS [returned combinations] FROM #combinations SELECT * FROM #combinations
@k = 5 다음 쿼리를 생성합니다 :
SELECT _1.value AS [1] , _2.value AS [2] , _3.value AS [3] , _4.value AS [4] , _5.value AS [5] , ROW_NUMBER() OVER (ORDER BY _1.value, _2.value, _3.value, _4.value, _5.value) AS combination FROM #set AS _1 INNER JOIN #set AS _2 ON _2.value > _1.value INNER JOIN #set AS _3 ON _3.value > _2.value INNER JOIN #set AS _4 ON _4.value > _3.value INNER JOIN #set AS _5 ON _5.value > _4.value
어느 그 다음 unpivots와 테이블에 덤프합니다.
동적의 SQL 못생긴, 당신은 UDF에 포장 할 수는 없지만 생산 된 쿼리가 매우 효율적입니다.
-
==============================
4.먼저이 UDF를 만들 ...
먼저이 UDF를 만들 ...
CREATE FUNCTION [dbo].[_ex_fn_SplitToTable] (@str varchar(5000), @sep char(1) = null) RETURNS @ReturnVal table (n int, s varchar(5000)) AS /* Alpha Test ----------- select * from [dbo].[_ex_fn_SplitToTable_test01]('abcde','') */ BEGIN declare @str2 varchar(5000) declare @sep2 char(1) if LEN(ISNULL(@sep,'')) = 0 begin declare @i int set @i = 0 set @str2 = '' declare @char varchar(1) startloop: set @i += 1 --print @i set @char = substring(@str,@i,1) set @str2 = @str2 + @char + ',' if LEN(@str) <= @i goto exitloop goto startloop exitloop: set @str2 = left(@str2,LEN(@str2) - 1) set @sep2 = ',' --print @str2 end else begin set @str2 = @str set @sep2 = @sep end ;WITH Pieces(n, start, stop) AS ( SELECT 1, 1, CHARINDEX(@sep2, @str2) UNION ALL SELECT n + 1, stop + 1, CHARINDEX(@sep2, @str2, stop + 1) FROM Pieces WHERE stop > 0 ) insert into @ReturnVal(n,s) SELECT n, SUBSTRING(@str2, start, CASE WHEN stop > 0 THEN stop-start ELSE 5000 END) AS s FROM Pieces option (maxrecursion 32767) RETURN END GO
그런 다음이 저장된 프로 시저를 만들 ...
CREATE proc [CombinationsOfString] ( @mystring varchar(max) = '0,5,10,15,20,25' ) as /* ALPHA TEST --------- exec CombinationsOfString '-20,-10,0,10,20' */ if object_id('tempdb..#_201606070947_myorig') is not null drop table #_201606070947_myorig CREATE TABLE #_201606070947_myorig ( SourceId int not null identity(1,1) ,Element varchar(100) not null ) insert into #_201606070947_myorig select s from dbo._ex_fn_SplitToTable(@mystring,',') --select SourceId, Element from #_201606070947_myorig declare @mynumerics varchar(max) set @mynumerics = ( select STUFF(REPLACE((SELECT '#!' + LTRIM(RTRIM(SourceId)) AS 'data()' FROM #_201606070947_myorig FOR XML PATH('')),' #!',', '), 1, 2, '') as Brands ) set @mynumerics = REPLACE(@mynumerics,' ','') print @mynumerics if object_id('tempdb..#_201606070947_source') is not null drop table #_201606070947_source if object_id('tempdb..#_201606070947_numbers') is not null drop table #_201606070947_numbers if object_id('tempdb..#_201606070947_results') is not null drop table #_201606070947_results if object_id('tempdb..#_201606070947_processed') is not null drop table #_201606070947_processed CREATE TABLE #_201606070947_source ( SourceId int not null identity(1,1) ,Element char(1) not null ) --declare @mynumerics varchar(max) --set @mynumerics = '1,2,3,4,5' insert into #_201606070947_source select s from dbo._ex_fn_SplitToTable(@mynumerics,',') -- select * from #_201606070947_source declare @Length int set @Length = (select max(SourceId) from #_201606070947_source) declare @columnstring varchar(max) = (SELECT REPLICATE('c.',@Length)) print @columnstring declare @subs varchar(max) = (SELECT REPLICATE('substring.',@Length)) print @subs if object_id('tempdb..#_201606070947_columns') is not null drop table #_201606070947_columns select s+CONVERT(varchar,dbo.PadLeft(convert(varchar,n),'0',3)) cols into #_201606070947_columns from [dbo].[_ex_fn_SplitToTable](@columnstring,'.') where LEN(s) > 0 if object_id('tempdb..#_201606070947_subcolumns') is not null drop table #_201606070947_subcolumns select s+'(Combo,'+CONVERT(varchar,n)+',1) ' + 'c'+CONVERT(varchar,dbo.PadLeft(convert(varchar,n),'0',3)) cols into #_201606070947_subcolumns from [dbo].[_ex_fn_SplitToTable](@subs,'.') where LEN(s) > 0 -- select * from #_201606070947_subcolumns -- select * from #_201606070947_columns declare @columns_sql varchar(max) set @columns_sql = ( select distinct stuff((SELECT distinct + cast(cols as varchar(50)) + ' VARCHAR(1), ' FROM ( select cols from #_201606070947_columns ) t2 --where t2.n = t1.n FOR XML PATH('')),3,0,'') from ( select cols from #_201606070947_columns ) t1 ) declare @substring_sql varchar(max) set @substring_sql = ( select distinct stuff((SELECT distinct + cast(cols as varchar(100)) + ', ' FROM ( select cols from #_201606070947_subcolumns ) t2 --where t2.n = t1.n FOR XML PATH('')),3,0,'') from ( select cols from #_201606070947_subcolumns ) t1 ) set @substring_sql = left(@substring_sql,LEN(@substring_sql) - 1) print @substring_sql set @columns_sql = LEFT(@columns_sql,LEN(@columns_sql) - 1) --SELECT @columns_sql declare @sql varchar(max) set @sql = 'if object_id(''tempdb..##_201606070947_01'') is not null drop table ##_201606070947_01 create table ##_201606070947_01 (rowid int,' + @columns_sql + ')' print @sql execute(@sql) CREATE TABLE #_201606070947_numbers (Number int not null) insert into #_201606070947_numbers select SourceId from #_201606070947_source CREATE TABLE #_201606070947_results ( Combo varchar(10) not null ,Length int not null ) SET NOCOUNT on DECLARE @Loop int ,@MaxLoop int -- How many elements there are to process SELECT @MaxLoop = max(SourceId) from #_201606070947_source -- Initialize first value TRUNCATE TABLE #_201606070947_results INSERT #_201606070947_results (Combo, Length) select Element, 1 from #_201606070947_source where SourceId = 1 SET @Loop = 2 -- Iterate to add each Element after the first WHILE @Loop <= @MaxLoop BEGIN INSERT #_201606070947_results (Combo, Length) select distinct left(re.Combo, @Loop - nm.Number) + so.Element + RIGHT(re.Combo, nm.Number - 1) ,@Loop from #_201606070947_results re inner join #_201606070947_numbers nm on nm.Number <= @Loop inner join #_201606070947_source so on so.SourceId = @Loop where re.Length = @Loop - 1 SET @Loop = @Loop + 1 END -- select * from #_201606070947_results -- Show #_201606070947_results SELECT * into #_201606070947_processed from #_201606070947_results where Length = @MaxLoop order by Combo -- select * from #_201606070947_processed set @sql = 'if object_id(''tempdb..##_201606070947_02'') is not null drop table ##_201606070947_02 ' print @sql execute(@sql) set @sql = ' ' + ' SELECT ROW_NUMBER() OVER(ORDER BY Combo Asc) AS RowID,' + @substring_sql + ' into ##_201606070947_02 ' + ' FROM #_201606070947_processed ' + ' ' PRINT @sql execute(@sql) declare @columns_sql_new varchar(max) set @columns_sql_new = REPLACE(@columns_sql,'(1)','(100)') set @sql = 'if object_id(''tempdb..##_201606070947_03'') is not null drop table ##_201606070947_03 create table ##_201606070947_03 (RowId int,' + @columns_sql_new + ')' PRINT @sql execute(@sql) insert into ##_201606070947_03 (RowId) select RowId from ##_201606070947_02 --select * from ##_201606070947_03 DECLARE @ColumnId varchar(10) DECLARE @getColumnId CURSOR SET @getColumnId = CURSOR FOR select cols ColumnId from #_201606070947_columns OPEN @getColumnId FETCH NEXT FROM @getColumnId INTO @ColumnId WHILE @@FETCH_STATUS = 0 BEGIN PRINT @ColumnId set @sql = ' ' + ' update ##_201606070947_03 set ' + @ColumnId + ' = B.Element from ##_201606070947_03 A , ( select A.RowID, B.* from ( select * from ##_201606070947_02 ) A , ( select * from #_201606070947_myorig ) B where A.' + @ColumnId + ' = B.SourceId ) B where A.RowId = B.RowId ' execute(@sql) print @sql FETCH NEXT FROM @getColumnId INTO @ColumnId END CLOSE @getColumnId DEALLOCATE @getColumnId select * from ##_201606070947_03
-
==============================
5.GROUP BY 절에 CUBE 확장은 주어진 목록의 모든 조합을 나타냅니다. 예컨대, 다음의 4 요소 세트의 모든 3의 조합을 제공한다.
GROUP BY 절에 CUBE 확장은 주어진 목록의 모든 조합을 나타냅니다. 예컨대, 다음의 4 요소 세트의 모든 3의 조합을 제공한다.
select concat(a,b,c,d) from (select 'a','b','c','d') as t(a,b,c,d) group by cube(a,b,c,d) having len(concat(a,b,c,d)) = 3
-
==============================
6.나는 조합을 계산하기위한 다른 기술을 가로 질러, 그것은 매우 간단합니다. 공공 SQL 도전, 그것은 또한 온전 내 (현재) 허용 대답에서와 동일한 비트 패턴 기술을 기반으로 내 자신의 시도를 이겼다. 나는 슈퍼 그것과 재생, 또는 여기에서 내 최적의 솔루션을 잡아 적응하지 않았다 인정하지만, 비록 내가 다시 이상 썼다.
나는 조합을 계산하기위한 다른 기술을 가로 질러, 그것은 매우 간단합니다. 공공 SQL 도전, 그것은 또한 온전 내 (현재) 허용 대답에서와 동일한 비트 패턴 기술을 기반으로 내 자신의 시도를 이겼다. 나는 슈퍼 그것과 재생, 또는 여기에서 내 최적의 솔루션을 잡아 적응하지 않았다 인정하지만, 비록 내가 다시 이상 썼다.
여기에 내가 아주 멋진 무언가에 명중하지만 나중에 내 솔루션을 쉽게 능가 발견 거라고 생각 - 어쨌든, 나는 확실히 나는 말뚝 아래로 자신을 촬영했다되었다. 나는이 기술을 시도하지만 놀랍게도, 그것은 위의 최선의 방법보다 더했다. 이 때문에 구현의 용이성과 (따라서 작업이 비트 패턴 기술과 같은의 복잡성을 요구할 수있는 경우를 제외하고는 우수한 만들기) 작은 작업에 대한 합리적인 성능 여기에 참조 할 수있다.
동시에 촬영 항목의 수를 항목으로부터 선택되는 것으로서 동일한 행 번호 변수 @K와 테이블 #set가 주어지면, 여기서 그 방법이다 :
WITH Chains AS ( SELECT Generation = 1, Chain = Convert(varchar(1000),'|' + Value + '|'), Value FROM #Set WHERE @K > 0 AND value <= ALL ( SELECT TOP (@K) Value FROM #Set ORDER BY Value DESC ) UNION ALL SELECT C.Generation + 1, Convert(varchar(1000), C.Chain + S.Value + '|'), S.Value FROM Chains C INNER JOIN #Set S ON C.Value < S.Value WHERE C.Generation <= @K ) SELECT C.Chain, S.Value FROM Chains C INNER JOIN #Set S ON C.Chain LIKE '%|' + S.Value + '|%' WHERE Generation = @K;
from https://stackoverflow.com/questions/3686062/generate-all-combinations-in-sql by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] SSRS보고에 어떻게 형식의 날짜와 시간을합니까? (0) | 2020.06.04 |
---|---|
[SQL] 다음 이벤트 날짜를 표시합니다 (0) | 2020.06.04 |
[SQL] PHP / MySQL의 우편 번호의 근접 검색 (0) | 2020.06.04 |
[SQL] SQL 서버 : SUM () 여기서 조항을 포함하여 여러 행의 (0) | 2020.06.04 |
[SQL] 스키마와 데이터 모두를위한 스크립트를 생성 (0) | 2020.06.04 |