2011-12-10 9 views
2

私は人のリストと期間の値を含むテーブルを持っています。テーブルの各人物の総所要時間を合計し、各人物のレコード数も表示する必要があります。カーソルを使用しないSQLの条件付きグループ化

PersonTable 
id int 
name nvarchar(max) 
duration decimal(18,2) 

SELECT name, sum(duration) as TotalDuration, count(*) as NumRecords 
FROM PersonTable 
GROUP BY name 

残念ながら、私は、残念ながら、3時間以上の時間を持つグループに人がいないようにする必要があります。特定の個人の合計レコードが3時間を超える場合は、その人のために2つのグループを生成する必要があります。合計を3未満にするために必要なものは2つ必要です。基本テーブルには、 > 3であるので、有効なグループのセットが常に可能です。明確にするために

試験データ:

id, person,  duration 
1, John Smith, 2hrs 
2, John Smith, 1hrs 
3, John Smith, 1hrs 
4, John Smith, 2hrs 
1, Jane Doe, 1hrs 
1, Jane Doe, 1hrs 
1, Jane Doe, 2hrs 
8, Jack Foo, 1hrs 

出力:(シーケンス番号が同一人物の異なるグループを識別するために)

name, Total Duration, Num Records, Sequence Number 
John Smith, 3hrs,  2,   1 
John Smith, 3hrs,  2,   2 
Jane Doe, 2hrs,  2,   1 
Jane Doe, 2hrs,  1,   2 
Jack Foo, 1hrs,  1,   1 

これは基本的な問題をissustrates。実際にはグループ化するフィールドが増えており、後で使用されるベースレコードのIDも列挙する必要があります。

私の現在の解決策は、ソートされたテーブルを反復処理するためにカーソルを使用し、累積合計時間が3を超えると新しいグループを一時テーブルに出力することです。また、temorparyテーブルには、グループ化に寄与するベーステーブルの

しかし、この種の問題に対して、より良い(カーソルがない)ソリューションがあるのだろうかと思います。
集計を元のテーブルに戻すことも可能ですか?そのため、上記のテーブルを再現するために、人とシーケンス番号をグループ化できるように、すべてのレコードのテーブルとシーケンス番号がありますか?これは、プロセスの後の段階で元のレコードを見つけるために使用されるカンマ区切りのidリストを作成するよりはるかに良い解決策になります。

+0

テーブルは 'プライマリKey'または発注やグループ化に使用されるいくつかの他の列を持っていますか? –

+0

はい、無地の自動インクリメントid列 – Trent

答えて

1

標準のSQLでやりたいことができないのではないかと心配です。問題は次のとおりです。特定の属性で行をグループ化すると、各行グループが常に1つの行に縮小されます。グループ化しないと、オリジナルと同じ数の行が作成されます。 3行のグループを2行に減らす方法はありません。

名前の列のグループ化された集約に基底テーブルを結合することは、元のテーブルと同じ数の行を取得するために役立ちません。この結合の結果をフィルタリングすることは、結合が同じ名前を持つすべての行に同じ情報を追加するため、結合の前より多くのものを区別することができないため、どちらにも役立ちません。

また、バックベーステーブルへの集約に参加することは可能なので、私は上記の表を再現するために、人とシーケンス番号にグループに私をできるように、すべてのレコードのテーブルに加え、シーケンス番号を持っているだろう?

シーケンス番号が各ネームグループ内で一意である場合、名前とシーケンス番号によるグループ化は、まったくグループ化しないことと同等です。したがって、一意でないシーケンス番号が必要です。つまり、同じ名前の一部の行は同じシーケンス番号を取得する必要があります。しかし、結果を再現するためのシーケンス番号の割り当てでは、シーケンス番号は、同じ名前とシーケンス番号を持つ行が決してsum> 3の持続時間を持たないように割り当てる必要があります。すでに問題を解決すること!

私は本当にあなたのカーソルのソリューションを行うための最も合理的なものだと思います。純粋なSQLはおそらくこれを解決できません。なぜなら、行のグループを複数の行に減らすことができないからです。

+0

だから何の解決策はありませんか?それから、その質問に答えます。 – Trent