|
分類:[.NET 全般]
SQLの組み立て方のアドバイスを頂けないでしょうか。C#、MySQLを使用しています。
以下のテーブルがあります。
■集会名簿テーブル
・メンバーID(int)
■ログテーブル
・メンバーID(int)
・出席(int) (基本的に1が登録されている)
・日付(Date) (データを登録した日付)
以下のような問題と条件があります。
@ある集会があり、集会の出席日数を1ヶ月間を通してカウントしたい
A例えばAさんが集会に出席した時にシステムにカードをかざすと、「1」とログテーブルに書き込まれる
B当日に1回カードをかざすと、2回目以降はカードをかざしてもDBに登録させない
C集会名簿テーブルにメンバーがいない場合はログテーブルに登録させない
Dカードをかざした時に1ヶ月以内の出席数を取得したい
E「出席」フィールドには「1」が入っている
F出席したデータはログテーブルに保存される
そこで以下のようなSQLを組み立てました。
// 集会名簿の中にメンバーがいるかの確認
select 集会名簿.メンバーID, 0 as カウント from 集会名簿 where 集会.メンバーID = @id
union all
// 当日、カードをかざして登録したユーザーはログテーブルに書き込ませない
select 集会名簿.メンバーID, 0 as カウント from 集会名簿 inner join ログテーブル on 集会名簿.メンバーID = ログテーブル.メンバーID WHERE 集会名簿.メンバーID = @id and ログテーブル.日付 = @今日 GROUP BY 集会名簿.メンバーID
union all
// 期間内の集計
select 集会名簿.メンバーID,sum(ログテーブル.出席) as カウント from 集会名簿 inner join ログテーブル on 集会名簿.メンバーID = ログテーブル.メンバーID where 集会名簿.メンバーID = @id and ログテーブル.日付 between @月初 and @月末 group by 集会名簿.メンバーID
SQLを実行して、結果をデータテーブルに入れます。0行であれば集会名簿に存在しない人のため、ログテーブルに登録させない。
1行、または2行結果が返ってきたら今日は登録されていないのでログテーブルに登録する。またここで出席の合計を取得する。
3行以上結果が返ってきたら今日は既に登録されているので登録しない。3行結果が返った時は集計は不要。というロジックで現在正しく動いているのですが、SQL部分が長すぎて、なんとなく無駄のような気がしてならないですが、何か良い実装方法があればお教え頂けないでしょうか。
|