質問があります。
環境
Delphi5.0
Interbase
現在、会議出席管理(出席か欠席)のプログラムを作成しています。
テーブルの構成は下記のようにしています。
このようなプログラムを作成するときは、出席簿テーブルに
出席データのみ登録するのがいいのか、出席・欠席データどちらも登録
するのがいいのか迷っています。
会員テーブル
・会員番号
・会員名称
会議テーブル
・会議番号
・会議日付
・会議名称
出席簿テーブル
・出席簿番号
・会議番号
・会員番号
・出席状態(0:欠席、1:出席)
(例)会員テーブル
1 会員A
2 会員B
(例)会議テーブル
1 会議A 2006/12/01
2 会議B 2007/01/01
2 会議C 2007/02/02
(例)出席簿テーブル(出席のみ登録)
1 1 1 1
2 3 1 1
3 3 2 1
(例)出席簿テーブル(欠席・出席登録)
1 1 1 1
2 1 2 0
3 2 1 0
4 2 2 0
5 3 1 1
6 3 2 1
//***************************************************************
出席のみ登録の場合、会議の出席・欠席状況を検索する方法はどのように
するとよろしいのでしょうか?
//***************************************************************
検索結果イメージ
会員A 会議A 出席
会員B 会議A 欠席
会員A 会議B 欠席
会員B 会議B 欠席
会員A 会議C 出席
会員B 会議C 出席
よろしくお願いします。
interbaseの環境がないので、未検証ですが
ACCESSの環境で書いてみました。(検索結果イメージのオーダーは考慮なしですが)参考になればどうぞ。
SELECT k.*, "欠席" AS 出欠席
FROM (SELECT 会員テーブル.会員番号, 会員テーブル.会員名, 会議テーブル.会議番号, 会議テーブル.会議日付, 会議テーブル.会議名称
FROM 会員テーブル, 会議テーブル) AS k LEFT JOIN 出席簿テーブル AS S ON (k.会員番号 = S.会員番号) AND (k.会議番号 = S.会議番号)
WHERE S.会議番号 Is Null
union all
SELECT k.*, "出席" AS 出欠席
FROM (SELECT 会員テーブル.会員番号, 会員テーブル.会員名, 会議テーブル.会議番号, 会議テーブル.会議日付, 会議テーブル.会議名称
FROM 会員テーブル, 会議テーブル) AS k LEFT JOIN 出席簿テーブル AS S ON (k.会員番号 = S.会員番号) AND (k.会議番号 = S.会議番号)
WHERE S.会議番号 Is not Null
ACCESSであれば、本当はIIF関数もあるので こんな記述にならないのですが、interbase不明なので 出席の抽出と欠席の抽出をUNIONで合わせました。
会員と会議のリストに、出席簿テーブルを外部結合しあれば「出席」なければ「欠席」で判断しています。
示してある例であれば、会員の情報に登録・脱会の考えがないですよね?
会議には日付を持っていますが、無条件に出席・欠席を並べるのは良いのですが 会議の時にまだ、未登録の会員とかの考慮まで先でする必要が出るのであればさらに、考慮が必要だと思います。
出席簿テーブルに出席・欠席データどちらも登録するかどうかは、どこまで処理したいかによります。もし出欠席の返事がないい場合は連絡するような事務処理が発生する場合は、出欠席を答えてもらわないといけません。
会員テーブルにメールアドレスがあれば、回答のない会員にEメールを送るようなプログラムもできますね。
出欠席を記入する場合、回答のない会員はnulを検索します。
会議テーブルに会議開始時間、開催場所、回答期限の項目を付加するのも良いかもしれません。
会議番号および会員番号で重複しないので、出席簿テーブルに出席簿番号はいらないような気がします。
AY、かずさん ありがとうございます。
こちらのテーブル名、項目名に置き換えてみましたが
うまく出来ないので下記の内容であっているのでしょうか?
"欠席" AS 出欠席 が私の勉強不足で意味がわかりません...
SELECT k.*, "欠席" AS 出欠席
FROM (SELECT CUSTOMER.CD, CUSTOMER.NAME, LECTURE.CD, LECTURE.LECTDATE, LECTURE.NAME
FROM CUSTOMER, LECTURE) AS k LEFT JOIN ROLLBOOK AS S ON (k.CD = S.SERIAL) AND (k.CD = S.SERIAL)
WHERE S.SERIAL Is Null
union all
SELECT k.*, "欠席" AS 出欠席
FROM (SELECT CUSTOMER.CD, CUSTOMER.NAME, LECTURE.CD, LECTURE.LECTDATE, LECTURE.NAME
FROM CUSTOMER, LECTURE) AS k LEFT JOIN ROLLBOOK AS S ON (k.CD = S.SERIAL) AND (k.CD = S.SERIAL)
WHERE S.CD Is not Null
会員テーブル(CUSTOMER)
・会員番号(CD)
・会員名称(NAME)
会議テーブル(LECTURE)
・会議番号(CD)
・会議日付(LECTDATE)
・会議名称(NAME)
出席簿テーブル(ROLLBOOK)
・出席簿番号(SERIAL)
・会議番号(LECT_CD)
・会員番号(CUST_CD)
・出席状態(ATTENDANCE)1:出席
よろしくお願いします。
"欠席" AS 出欠席
これは、欠席という文字列を固定で返しています
存在したら「出席」の文字を 存在しなかったら「欠席」の文字を。
説明にも書きましたがACCESSで書いています。
(出欠席の漢字文字はやめた方がよいかも)
ACCESSでは、文字列を””でくくるのでそうしていますが
interbaseでは違うかもしれません
その部分は、確認されるとして 実際にはCDで名前がダブっていたのですね
CDに別名を付加しました
SELECT k.*, "欠席" AS syuketu
FROM (SELECT CUSTOMER.CD as CCD, CUSTOMER.NAME, LECTURE.CD as LCD, LECTURE.LECTDATE, LECTURE.NAME
FROM CUSTOMER, LECTURE) AS k LEFT OUTER JOIN ROLLBOOK AS S ON (k.CCD = S.CUST_CD) AND (k.LCD = S.LECT_CD)
WHERE S.SERIAL Is Null
union all
SELECT k.*, "欠席" AS syuketu
FROM (SELECT CUSTOMER.CD as CCD, CUSTOMER.NAME, LECTURE.CD as LCD, LECTURE.LECTDATE, LECTURE.NAME
FROM CUSTOMER, LECTURE) AS k LEFT OUTER JOIN ROLLBOOK AS S ON (k.CCD = S.CUST_CD) AND (k.LCD = S.LECT_CD)
WHERE S.CD Is not Null
あっ、WHEREでNULLかどうか条件付けしてる項目は、結果は一緒ですが
同じ項目が良いですね。
(変える意味はないので・・)
そのままコピーしてよく見ていませんでしたが
unionの次のSELECTは、存在している時なので 欠席ではなく出席ですね。
AYさん、ありがとうございます。
親切にご指導いただきありがとうございました。
Interbase(FireBird)ではエラーになるみたいです...
実行できませんでした。
他に方法はないですか?
他に方法ですか・・
Interbase(FireBird)ではエラーとの事ですが、SQL文の書き方の問題なのでInterbaseに合わないところがあれば、それ様に書き直す必要はありますよ。
どこがエラーになるか、SQLをばらしてチェックされてはどうですか?
1.会員と会議の副問い合わせのところですか?
2.それとも、それに出席状態を結合したところですか?
3."欠席" の記述のところでしょうか?
と言うように、エラーが特定できるように細分化して確認されてはどうでしょう。
ツイート | ![]() |