2010-02-13 5 views
3

된 table_1
D_ID 정수
Deposit_amt 정수은 그 합계 (다른 테이블 또는 AMT) 특정 량

Table_2

Total_amt 정수

를 Total_ID까지 추가 행의 조합을 찾기

Table_1에있는 모든 행을 찾으려면 select 문을 쓸 수 있습니까? Deposit_amt 합계 Total_amt (Table_2) 두 테이블에 여러 행이 있습니다.

Table_2의 첫 번째 행은 Total_amt=100입니다. 나는 Table_1에서 D_ID 2, 6, 12 합계 = 100, 행 D_ID 2, 3, 42 합계 = 100 등으로 행을 알고 싶습니다.

도움말 감사합니다. 내가 분명히해야하는지 알려줘.

나는이 질문에 거래의 목록과 합계 목록이있는 사람으로서 자신이 합계를 만들 수있는 가능한 거래 목록을 찾아야한다고 말합니다. 총액 합계가 총액을 창출했음을 보장하지는 않는 거래의 조합을 찾는 것이 위험한 것처럼 보입니다.

나는 그것이 np-complete 문제라는 것을 몰랐다.

+5

표 2의 모든 행에 대해 NP-Complete 하위 집합 합계 문제 (http://en.wikipedia.org/wiki/Subset_sum_problem)를 해결 하시겠습니까? SQL에서? 왜? 배경을 줄 수 있어요? –

+0

이것은 정신 이상입니다. 가능한 모든 조합을 시도해보십시오.!? –

+0

흠,이게 NP-Complete라는 것을 몰랐다. 나는 수 년 전 무차별 방식으로 다행히 해결했다. (다행스럽게도 각 세트에 몇백 개 요소가있다.) 나는 언젠가 그것에 대해 CW 질문을하는 것을 실제로 생각하고 있었다. .. 지금 나는 걱정하지 않을 것이다! – Aaronaught

답변

2

합니다. Total_amt까지 추가되는 하나, 둘 또는 세 개의 레코드 조합을 찾습니다.

Total_amt d1_ID  d1_amt  d2_ID  d2_amt  d3_ID  d3_amt 
----------- ----------- ----------- ----------- ----------- ----------- ----------- 
4   3   1   2   3   NULL  NULL 
4   4   1   2   3   NULL  NULL 
4   1   4   NULL  NULL  NULL  NULL 
4   10   4   NULL  NULL  NULL  NULL 
17   9   12   3   1   1   4 
17   9   12   4   1   1   4 
17   10   4   5   9   1   4 
17   8   7   7   6   1   4 
17   6   13   1   4   NULL  NULL 
17   10   4   6   13   NULL  NULL 
17   10   4   8   7   7   6 
17   8   7   5   9   4   1 
17   10   4   9   12   4   1 
17   8   7   5   9   3   1 
17   10   4   9   12   3   1 
17   6   13   3   1   2   3 
17   6   13   4   1   2   3 
23   8   7   6   13   2   3 
23   6   13   5   9   3   1 
23   6   13   5   9   4   1 
23   10   4   7   6   6   13 
23   10   4   9   12   8   7 
23   7   6   6   13   1   4 
23   9   12   8   7   1   4 

(24 row(s) affected) 

참고 : 당신은 개별 행을 필터링 할 수 있습니다 당신은 d4, d5 부속 선택 등 :

begin tran 

create table Table_1 (D_ID int, Deposit_amt int) 
create table Table_2 (Total_ID int, Total_amt int) 

insert into Table_1 (D_ID, Deposit_amt) values (1, 4) 
insert into Table_1 (D_ID, Deposit_amt) values (2, 3) 
insert into Table_1 (D_ID, Deposit_amt) values (3, 1) 
insert into Table_1 (D_ID, Deposit_amt) values (4, 1) 
insert into Table_1 (D_ID, Deposit_amt) values (5, 9) 
insert into Table_1 (D_ID, Deposit_amt) values (6, 13) 
insert into Table_1 (D_ID, Deposit_amt) values (7, 6) 
insert into Table_1 (D_ID, Deposit_amt) values (8, 7) 
insert into Table_1 (D_ID, Deposit_amt) values (9, 12) 
insert into Table_1 (D_ID, Deposit_amt) values (10, 4) 

insert into Table_2 (Total_ID, Total_amt) values (1, 17) 
insert into Table_2 (Total_ID, Total_amt) values (2, 23) 
insert into Table_2 (Total_ID, Total_amt) values (3, 55) 
insert into Table_2 (Total_ID, Total_amt) values (4, 4) 

select t.Total_amt, 
    d1.D_ID as d1_ID, d1.Deposit_amt as d1_amt, 
    d2.D_ID as d2_ID, d2.Deposit_amt as d2_amt, 
    d3.D_ID as d3_ID, d3.Deposit_amt as d3_amt 
from Table_2 t 
cross join (
    select D_ID, Deposit_amt from Table_1 
) d1 
inner join (
    select D_ID, Deposit_amt from Table_1 
    union all 
    select null, null 
) d2 on d1.D_ID > d2.D_ID or d2.D_ID is null 
inner join (
    select D_ID, Deposit_amt from Table_1 
    union all 
    select null, null 
) d3 on d2.D_ID > d3.D_ID or d3.D_ID is null 
where isnull(d1.Deposit_amt, 0) + isnull(d2.Deposit_amt, 0) + isnull(d3.Deposit_amt, 0) = t.Total_amt 
order by Total_amt 

rollback tran 

출력을 추가하여 그것이 합 당 더 많은 트랜잭션을 처리하기 위해 확장 할 수 Deposit_amt > Total_amt이지만 Deposit_amt의 색인을 생성하지 않으면 성능이 크게 향상되지 않을 수 있습니다.

3

당신의 친구에게이를주고, 그녀의 행운을 기원합니다 .. : P에게 나는 무력 솔루션을했다 그냥 재미를 위해 XKCD reference image

0
CREATE TABLE #N1 (ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED, Val INT) 
CREATE TABLE #N2 (ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED, Val INT) 

-- SELECT TOP 20 'INSERT INTO #N1 (Val) VALUES (' + CAST (CAST (RAND (CAST (NEWID() AS VARBINARY)) * 100 AS INT) AS VARCHAR) + ')' FROM sys.objects 
INSERT INTO #N1 (Val) VALUES (93) 
INSERT INTO #N1 (Val) VALUES (93) 
INSERT INTO #N1 (Val) VALUES (86) 
INSERT INTO #N1 (Val) VALUES (23) 
INSERT INTO #N1 (Val) VALUES (51) 
INSERT INTO #N1 (Val) VALUES (85) 
INSERT INTO #N1 (Val) VALUES (93) 
INSERT INTO #N1 (Val) VALUES (27) 
INSERT INTO #N1 (Val) VALUES (12) 
INSERT INTO #N1 (Val) VALUES (15) 
INSERT INTO #N1 (Val) VALUES (23) 
INSERT INTO #N1 (Val) VALUES (87) 
INSERT INTO #N1 (Val) VALUES (94) 
INSERT INTO #N1 (Val) VALUES (61) 
INSERT INTO #N1 (Val) VALUES (15) 
INSERT INTO #N1 (Val) VALUES (86) 
INSERT INTO #N1 (Val) VALUES (38) 
INSERT INTO #N1 (Val) VALUES (81) 
INSERT INTO #N1 (Val) VALUES (67) 
INSERT INTO #N1 (Val) VALUES (45) 

-- SELECT TOP 20 'INSERT INTO #N2 (Val) VALUES (' + CAST (CAST (RAND (CAST (NEWID() AS VARBINARY)) * 100 AS INT) AS VARCHAR) + ')' FROM sys.objects 
INSERT INTO #N2 (Val) VALUES (32) 
INSERT INTO #N2 (Val) VALUES (1) 
INSERT INTO #N2 (Val) VALUES (24) 
INSERT INTO #N2 (Val) VALUES (20) 
INSERT INTO #N2 (Val) VALUES (40) 
INSERT INTO #N2 (Val) VALUES (25) 
INSERT INTO #N2 (Val) VALUES (37) 
INSERT INTO #N2 (Val) VALUES (19) 
INSERT INTO #N2 (Val) VALUES (47) 
INSERT INTO #N2 (Val) VALUES (23) 
INSERT INTO #N2 (Val) VALUES (7) 
INSERT INTO #N2 (Val) VALUES (53) 
INSERT INTO #N2 (Val) VALUES (75) 
INSERT INTO #N2 (Val) VALUES (82) 
INSERT INTO #N2 (Val) VALUES (15) 
INSERT INTO #N2 (Val) VALUES (26) 
INSERT INTO #N2 (Val) VALUES (22) 
INSERT INTO #N2 (Val) VALUES (70) 
INSERT INTO #N2 (Val) VALUES (17) 
INSERT INTO #N2 (Val) VALUES (1) 

SELECT #N1.ID, #N2.ID, t.Val1, t.Val2 
FROM (
SELECT 
    #N1.Val AS Val1 
, #N2.Val AS Val2 
FROM #N1,#N2 
WHERE #N1.Val+#N2.Val=100 
) AS t 
INNER JOIN #N1 ON #N1.Val = t.Val1 
INNER JOIN #N2 ON #N2.Val = t.Val2 
관련 문제