2012-07-08 34 views
0

我與田(QuestionID,QuestionMarks)一個問題表,並用數據字段的樣子 -SQL服務器計數和總和查詢?

QuestionID QuestionMarks 
    1    1 
    2    4 
    5    1 
    9    1 
    12    2 

,這意味着目前的問題表中有5題共9痕跡,現在我的問題是我想知道4個問題與8個標記的組合是可能的,並提取出該組合(通常可以使用「y」標記的「x」個問題的組合)?

我想使用CTE,但擔心如果我有幾萬個問題,執行查詢會花費很多時間。

請提出一些想法如何獲取數據。我正在使用SQL Server版本2008

+0

要麼我計算錯誤,要麼你的樣本和評論不匹配(我在你的樣本中共有8個標記)。另外,無論你如何切片,我認爲這是一次組合爆炸。 – 2012-07-08 05:14:03

+0

對不起,這是我的錯誤與QuestionID = 12的最後一個問題是標記2,現在編輯 – 2012-07-08 05:16:54

+0

@Damien_The_Unbeliever - 所以沒有安全的方式來在SQL中執行它? – 2012-07-08 05:18:54

回答

0

這是一個開始。這將有表現不佳:

declare @Qs table (QuestionID int not null, QuestionMarks int not null) 
insert into @Qs (QuestionID,QuestionMarks) values 
(1,1), (2,4), (5,1), (9,1), (12,2) 

declare @TargetMarks int = 8 
declare @TargetCount int = 4 

;with Build as (
    select QuestionID as MinID,QuestionID as MaxID,QuestionMarks as Total,1 as Cnt 
     ,'/' + CONVERT(varchar(max),QuestionID) + '/' as QPath 
    from @Qs 
    union all 
    select MinID,q.QuestionID,Total+q.QuestionMarks,Cnt+1,QPath + CONVERT(varchar(max),q.QuestionID) + '/' 
    from 
     Build b 
      inner join 
     @Qs q 
      on 
       b.MaxID < q.QuestionID and 
       b.Total + q.QuestionMarks <= @TargetMarks and 
       b.Cnt < @TargetCount 
) 
select * from Build where Cnt = @TargetCount and Total = @TargetMarks 

結果集:

MinID  MaxID  Total  Cnt   QPath 
-------------------------------------------------------------------------------- 
2   12   8   4   /2/5/9/12/ 
1   12   8   4   /1/2/9/12/ 
1   12   8   4   /1/2/5/12/ 

棘手的部分是,QPath值是不完全存儲ID值最大的方式。

+0

感謝哥們,讓我明白它,並會回覆給你。只是想知道,這個解決方案將是好的表現明智,就像我有成千上萬的表在行? – 2012-07-08 05:34:14

+0

@ user1509581 - 要知道的唯一方法就是在您的硬件/操作系統上使用您的數據進行試用,並設置特定的性能標準 - 一個人可以接受什麼可能不適用於另一個 - 您是否需要結果< 1秒鐘,幾秒鐘,幾分鐘,或者只是在宇宙熱量死亡之前。表現非常主觀。 – 2012-07-08 05:37:04

+0

明白了你的觀點,幾秒鐘後對我來說會好起來的,反正到現在爲止機器運行完好無損。 Thx – 2012-07-08 05:42:22

0

我認爲你說得對,成千上萬的問題可能會減慢執行速度,所以我會先限制被查詢的潛在行。您已經知道,即使擁有數百萬行,您也永遠不會需要超過四個具有相同QuestionMark的行,並且您可以進一步減少這些行數。 (對不起,不知道SQL Server是否接受此語法)

WITH LimitPotentialRows AS 
(SELECT m1.QuestionID, m1.QuestionMarks, 
(SELECT SUM(m2.QuestionMarks) 
    FROM MyTable m2 
    WHERE m1.QuestionMarks = m2.QuestionMarks 
    AND m1.PrimaryKeyID <= m2.PrimaryKeyID) CurrentMarks, 
(SELECT COUNT(*) 
    FROM MyTable m3 
    WHERE m1.QuestionMarks = m3.QuestionMarks 
    AND m1.PrimaryKeyID <= m3.PrimaryKeyID) TotalQuestions 
FROM MyTable m1 
WHERE m1.QuestionMarks <= :DesiredTotalQuestionMarks - :TotalNoOfQuestions + 1 
HAVING CurrentMarks <= :DesiredTotalQuestionMarks 
    AND TotalQuestions <= :TotalNoOfQuestions) 

切盼4題,共8個商標,這CTE的結果會讓你只

QuestionMarks NumberOfQuestions 
     1    4 
     2    4 
     3    2 
     4    1 
     5    1 

具有有限數量從成千上萬行到最多12行,您在進一步的計算中不會出現性能問題。