2010-02-13 53 views
3

TABLE_1
D_ID整數
Deposit_amt整數在SQL找到其總和加起來特定的量(或AMT在其他表)

TABLE_2
Total_ID
Total_amt整數

行的組合

是否有可能編寫select語句來查找Table_1中的所有行,其總和爲Deposit_amt 中的Total_amt。兩個表中都有多行。

說第一行Table_2有一個Total_amt=100。我想知道在Table_1D_ID 2,6,12總結= 100,行D_ID 2,3,42求和= 100等。

幫助讚賞。如果我需要澄清,請告訴我。

我在問這個問題,因爲某人作爲他們工作的一部分有一個交易清單和一個總計清單,她需要找到可能創建總計的交易清單。我同意這聽起來很危險,因爲找到合計的總數並不能保證他們創造了總數。

我不知道這是一個NP完整的問題。

+5

你的意思是你想爲表2中的每一行解決NP-Complete Subset Sum Problem(http://en.wikipedia.org/wiki/Subset_sum_problem)?在SQL?爲什麼?你能給一些背景嗎? – 2010-02-13 00:13:08

+0

這是瘋狂..嘗試所有可能的組合?!? – 2010-02-13 00:19:47

+0

呵呵,我不知道這是NP-Complete,很多年前我用強力方法「解決」了它(幸運的是,它每套只有幾百個元素)。我實際上想着有一天會問CW的問題......現在我不打擾! – Aaronaught 2010-02-13 00:44:09

回答

2

只是爲了好玩,我做了蠻力解決方案。它將查找總計爲Total_amt的一個,兩個或三個記錄的組合。你可以擴展它來處理每總和更多的交易,通過增加d4d5子查詢,等:

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 

輸出:

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) 

注:你可以篩選出各行其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 
相關問題