0

フィールド(QuestionID、QuestionMarks)を含むQuestionテーブルがあり、データフィールドは次のようになります-

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

つまり、現時点では、質問テーブルには合計 9 マークの 5 つの質問があります。ここで私の問題は、4 つの質問と 8 つのマークの組み合わせが可能であることを知り、その組み合わせを取得することです (一般に、「x」の質問の組み合わせ"y" マークの可能性があります) ?

CTEを使おうと思っていたのですが、何万もの質問があるとクエリの実行に時間がかかるのではないかと心配でした。

データを取得する方法をいくつか提案してください。SQL Server バージョン 2008 を使用しています

4

2 に答える 2

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 値を格納する最適な方法ではないことです。

于 2012-07-08T05:27:45.463 に答える
0

何万もの質問が実行を遅くする可能性があるという点であなたは正しいと思うので、クエリされる可能性のある行を制限することから始めます. 何百万もの行があっても、同一のクエスチョンマークが 4 つ以上必要になることはなく、これをさらに減らすことができることはすでに確実にわかっています。たとえば、(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)

合計 8 点の 4 つの質問を希望する場合、この CTE の結果は、

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

行数を数万から最大 12 に制限したので、その後の計算でパフォーマンスの問題が発生する可能性はほとんどありません。

于 2012-07-08T07:40:47.063 に答える