私は人のリストと期間の値を含むテーブルを持っています。テーブルの各人物の総所要時間を合計し、各人物のレコード数も表示する必要があります。カーソルを使用しない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リストを作成するよりはるかに良い解決策になります。
テーブルは 'プライマリKey'または発注やグループ化に使用されるいくつかの他の列を持っていますか? –
はい、無地の自動インクリメントid列 – Trent