복붙노트

[SQL] SQL의 모든 조합을 생성

SQL

SQL의 모든 조합을 생성

나는 크기 @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. ==============================

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

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

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

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

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

    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;
    
  7. from https://stackoverflow.com/questions/3686062/generate-all-combinations-in-sql by cc-by-sa and MIT license