C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: 集計SQL文


(過去ログ 172 を表示中)

[トピック内 2 記事 (1 - 2 表示)]  << 0 >>

■98988 / inTopicNo.1)  集計SQL文
  
□投稿者/ すずさと (1回)-(2022/01/26(Wed) 11:37:49)

分類:[.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部分が長すぎて、なんとなく無駄のような気がしてならないですが、何か良い実装方法があればお教え頂けないでしょうか。

引用返信 編集キー/
■98989 / inTopicNo.2)  Re[1]: 集計SQL文
□投稿者/ shu (1270回)-(2022/01/26(Wed) 14:14:07)
No98988 (すずさと さん) に返信

Select a.メンバーID, count(b.メンバーID) cnt
From 集会名簿テーブル a left join (select メンバーID from ログテーブル where 日付=@今日) b on a.メンバーID = b.メンバーID
where a.メンバーID = @id
group by a.メンバーID;


メンバーがいない:レコード数0
メンバーがいる :cnt = 今日のログレコード数

となる。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -