2015-01-12 6 views
1

SQL 서버의 행의 모든 ​​가능한 조합 2008 R2SQL 쿼리 : 합계, 테이블

예제 테이블 구조

create table TempTable 
(
    ID int identity, 
    value int 
) 

insert into TempTable values(6) 
insert into TempTable values(7) 
insert into TempTable values(8) 
insert into TempTable values(9) 
insert into TempTable values(10) 

실제로 그것은, 그것은 갖도록 행을 반환이 뭔가를 원하는 아래에 표시된 것처럼 나머지 모든 행의 합계.

6+7 
6+8 
6+9 
6+10 

6+7+8 
6+7+9 
6+7+10 


6+8+9 
6+8+10 

6+9+10 

6+7+8+9 

6+7+8+9+10 

AronLS 솔루션이 내 요구를 충족시키고 있습니다. 그러나 며칠 동안 질문을 공개하십시오. 1. 내가 할 수있는 또 다른/더 좋은 방법이 있습니까?

+0

사용중인 sql-server의 버전은 무엇입니까? – Hatsjoem

+0

SQL Server 2008 R2 – user2647784

+0

왜 '6 + 7 + 8 + 9 + 10' ** 및 **'10 + 6 + 7 + 8 + 9 '를 원하십니까? 둘 다 동일한 결과를 얻을 것입니다. –

답변

3

이것은 "모든 가능한 순열"문제는 자체 조인과 재귀 적 CTE로 해결할 수 있습니다. 우리가 다른 파괴 기준이없고 허용 재귀의 수를 능가하기 때문에 t1.ID < t2.ID

재귀의 깊이를 제한 :

With selfrec as (
    Select t.Value, t.ID, 0 as Level From TempTable t 
     UNION ALL 
    Select t2.Value + t1.Value as Value, t1.ID, Level + 1 From TempTable t1 
    Inner Join selfrec t2 on t1.ID < t2.ID 
    Where Level < 4 -- limit the number of recursions 
) 
Select * From selfrec 
Order By Level 

이 기준은 순열 콤보의 중복 역전을 자신을 일치뿐만 아니라, 가진 항목을 제거 : 약간의 꾸밈 Where Level < 4

+0

감사합니다. 그러나 그 결과는 어떤 차이가 있습니다. 또한 t2.ID에 오류가 발생합니다. – user2647784

+0

@ user2647784 다시 시도하고 싶다면 거기에 실수가 있었기 때문에 몇 번 편집했습니다. 행운을 빌어 요 – AaronLS

+0

@ user2647784 그리고 데이터베이스가 대소 문자를 구분하도록 구성되어 있다면'ID' 대'Id'에 오류가 발생할 수 있습니다. – AaronLS

1

FWIW-- , 당신은 무슨 일이 일어나고 있는지 볼 수 있습니다

CREATE TABLE #TempTable 
(
    Expr VARCHAR(10), 
    ID INT IDENTITY, 
    value INT 
) 

INSERT INTO #TempTable VALUES('6', 6) -- a 
INSERT INTO #TempTable VALUES('7', 7) -- b 
INSERT INTO #TempTable VALUES('8', 8) -- c 
INSERT INTO #TempTable VALUES('9', 9) -- d 
INSERT INTO #TempTable VALUES('10', 10) -- e 

SELECT expr, value FROM #TempTable 

-- Choose(n,k) = n!/(n!(n-k)!) [order not important] 
-- n = 5, k = {1,2,3,4,5} 

-- C(5,1) + C(5,2) + C(5,3) + C(5,4) + C(5,5)  
-- 5 + 10 + 10 + 5 + 1  = 31 
-- There should be 31 rows. 
------ 
; 
WITH selfrecCTE AS 
( 
    SELECT 
     CAST(expr AS VARCHAR(100)) AS Expr 
     , T.value 
     , T.ID 
     , 0 AS Level 
    FROM 
     #TempTable AS T 
    UNION ALL 
    SELECT 
     CAST(t1.expr + ' + ' + T2.expr AS VARCHAR(100)) AS Expr 
     , T2.value + T1.value AS Value 
     , T1.ID 
     , Level + 1 
    FROM 
     #TempTable T1 
     INNER JOIN selfrecCTE T2 
     ON T1.ID < T2.ID 
    --WHERE 
    -- Level < 4 -- limit the number of recursions 
) 
    -- 31 rows. OK. 
    SELECT * FROM selfrecCTE 
    ORDER By id, expr, Level 

나는 이것을 재미있는 전환이라고 생각했습니다. 질문 해 주셔서 감사합니다.