Microsoft Access 掲示板

日付の抜け漏れチェック

18 コメント
views
4 フォロー
氏名会社所属開始日終了日
あああxxxxx経理2000/12/31
あああxxxxx人事2001/1/12010/3/31
あああxxxxx総務2010/4/12018/8/31
あああxxxxx経理2018/9/12020/3/31
あああxxxxx人事2020/4/1
・・・
いいいxxxxx営業2010/4/12019/1/31
いいいxxxxx経理2019/2/12022/3/31
いいいxxxxx人事2022/4/1
・・・
  
最初の開始日は管理していたり、いなかったり(あるとは限らない)
現在継続している場合は、終了日がない

サンプルでは、人ごとに会社ごとに日付がつながっている状態ですが、
抜けているレコードに対してフラグを立てるなど
日付がつながっていないようなエラーを発見するロジックを作成したいと思っています。

よろしくお願いいたします。

もっちー
作成: 2022/04/07 (木) 19:29:57
最終更新: 2022/04/07 (木) 22:02:19
通報 ...
1

下記のSQLで 開始日の1日前の終了日が存在しない場合、チェックが True になります。

SELECT T1.*, T2.終了日 IS NULL AS チェック
FROM テーブル1 AS T1 LEFT JOIN テーブル1 AS T2
 ON T1.氏名=T2.氏名 AND T1.会社=T2.会社 AND T1.開始日-1=T2.終了日;
2
もっちー 2022/04/07 (木) 22:45:27 2acb4@c8d31

hatena様

なるほど、開始日の1日前の終了日が存在しないという条件で判定をするのですか。

どうもありがとうございます。明日、早速試してみます。

4
もっちー 2022/04/08 (金) 17:56:53 d73a2@c8d31

| 氏名    | 会社    | 所属 | 開始日   | 終了日   |
| ううう  |   ZZZZZ  | 法務 | 2020/4/1 | 2021/3/31 |
| ううう  |   TTTTT  | 法務 | 2021/4/1 | 2022/3/31 |
| ううう  |   EEEEE  | 法務 | 2022/4/1 |   NULL   |

試したところ、なかなかうまく判定ができていません。
例えば、こんなケースもありまして、これはエラーではないと判断したいです。
出向等をして、1レコードで完結している場合など。

よろしくお願いいたします。

5
りんご 2022/04/10 (日) 03:33:08 c564b@0e907 >> 4

試していませんが、氏名と開始日で外部結合すれば、会社違いのエラー判定を回避できるのかも。

6
りんご 2022/04/10 (日) 04:25:26 c564b@0e907

日付がつながっていないようなエラー

 終了したら翌日には開始、空白が生じたらエラーという事でしょうか。例えば、終了日4/10日、次の開始日4/12日の場合、どちらをエラーと判定するのでしょう。正しくは、終了日4/11日、次の開始日4/12日、それとも、終了日4/10日、次の開始日4/11。あるいは、終了日と開始日、どちらもエラーなんてことも。

現在継続している場合は、終了日がない

 9999/12/31で登録しておくとか。

サンプルでは、人ごとに会社ごとに日付がつながっている状態ですが、

 氏名と開始日に複合主キーを設定して、登録の仕組みを整えるといいかも。

7
もっちー 2022/04/11 (月) 11:32:06 d73a2@c8d31

アドレスありがとうございます。

サンプルはエラーの発生が無い想定でおだししています。

実データが、終了日4/10日、次の開始日4/12日だった場合、どらのレコードもエラーとしたいです。
正しいデータはいくつかの可能性がありますが、そこは気にせず、単につながりがないレコードを抽出し、
人間が確認をして、正しいデータに修正をすることで、結果、エラーが回避されれば良いと考えています。

運用面で、9999/12/31を使うとか、複合キーの設定も検討はしてみたいと思います。

8
hiroton 2022/04/11 (月) 15:01:56 2eeb4@f966d

「氏名」だけのチェックでいいのであれば AND T1.会社=T2.会社を削除すればいいです。そもそも「氏名」「会社」の判定部分は本題とはずれた話ですね。同姓同名問題があるので破綻します。「個人」を特定するためにユニークなキーを設定しましょう


日付で起こりうるエラー

  1. 開始日・終了日共に未入力のデータがある(同一人物すべてのレコードが正しいとは言えなくなる
  2. 開始日が、未入力、かつ、それ以前のデータがある
  3. 終了日が、未入力、かつ、それ以降のデータがある
  4. 最初でないレコードで開始日の前日の終了日がない
  5. 最後でないレコードで終了日の翌日の終了日がない
  6. 開始日が、別なレコードの開始日から終了日(未入力含む)の間にある
  7. 終了日が、別なレコードの開始日(未入力含む)から終了日の間にある

エラーとはどのようなデータのことなのか明確にしてhatenaさんが提示したようなSQLを作ってつなげればいいと思いますよ

SQLでやると起こりうるエラー毎にテーブルの参照が必要になるんでhirotonならVBAでエラーレコードの拾い出しにしそうですけどね

9

とりあえず下記でどうでしょう。

SELECT T1.*,
 T2.終了日 Is Null And
 Not (T1.開始日 Is Null OR T1.開始日=DMin("開始日","テーブル1","氏名='" & T1.氏名 & "'")) AS 開始日非連続,
 T3.開始日 Is Null And
 Not (T1.終了日 Is Null OR T1.終了日=DMin("終了日","テーブル1","氏名='" & T1.氏名 & "'")) AS 終了日非連続
FROM
 (テーブル1 AS T1 LEFT JOIN テーブル1 AS T2 ON (T1.開始日-1=T2.終了日) AND (T1.氏名=T2.氏名))
 LEFT JOIN テーブル1 AS T3 ON (T1.終了日+1=T3.開始日) AND (T1.氏名=T3.氏名);

出力結果例

ID氏名会社所属開始日終了日開始日非連続終了日非連続
1あああxxxxx経理2000/12/3100
2あああzzzzz人事2001/01/012010/03/310-1
3あああttttt総務2010/04/022018/08/31-10
4あああxxxxx経理2018/09/012020/03/3100
5あああxxxxx人事2020/04/0100
6いいいxxxxx営業2010/04/012019/01/3100
7いいいxxxxx経理2019/02/012022/03/3100
8いいいxxxxx人事2022/04/012022/05/3100

ただし上記のクエリは更新不可になりますので、
この結果を見ながらテーブルを修正することになります。

10

hirotonさんが厳密なエラー例を出してますが、
上記のクエリは、このなかの、2. 3. 6. 7. はエラーになりません。

すべてのエラーに対応するなら、hirotonさん同様VBAを検討しますね。

11
もっちー 2022/04/14 (木) 21:55:18 2acb4@c8d31

みなさま

申し訳ございません。忙殺されていまして、確認が遅くなりました。
アドバイスを試してみて、後程フィードバックさせていただきます。

ひとまずご連絡まで。

13
もっちー 2022/04/15 (金) 12:57:04 9a1c9@94ff5

厳密なチェックを要するものではありませんので、
hatenaさまのSQLを利用させていただいております。

1点だけ要件を加えさせていただいております。
T1からT2, T3に外部結合する際、氏名、出向元、出向先フィールで結合をするように修正し、
重複レコードが作られるので、Distinctをしております。
演算フィールドのDMin条件には、氏名、出向元、出向先が一対するものと修正いたしました。
データシートは表示できるのですが、あいまいな外部結合が含まれるため、SQLが表示されません。

元データ
| 氏名     | 出向元    |出向先   | 兼務率    |開始日  | 終了日   |
| -------- | -------- | -------- | -------- | -------- | -------- |
| サンプル  | AAA      | あああ  | 50%       | 2017/1/1 | 2022/3/31|
| サンプル  | AAA      | ううう  | 50%       | 2017/1/1 | 2022/3/31|
| サンプル  | AAA      | いいい | 0%        | 2021/12/1| 2022/3/31|
| サンプル  | AAA      | ううう | 100%      | 2022/4/1 |          |
| サンプル  | AAA      | あああ | 0%        | 2022/4/1 |          |

SQL実行結果
| 氏名    | 出向元    |出向先   | 兼務率   |開始日  |終了日  | 開始フラグ |終了フラグ|
| -------- | -------- | --------| ---- | -------- | -------- | -------- | -------- |
| サンプル  | AAA      | あああ  | 50%  | 2017/1/1 | 2022/3/31 |     0 |    0    |
| サンプル  | AAA      | ううう  | 50%  | 2017/1/1 | 2022/3/31 |     0 |    0    |
| サンプル  | AAA      | いいい | 0%   | 2021/12/1| 2022/3/31 |     0 |    0    |
| サンプル  | AAA      | ううう | 100% | 2022/4/1 |           |     0 |    0    |
| サンプル  | AAA      | ううう | 100% | 2022/4/1 |           |    -1 |    0    |
| サンプル  | AAA      | あああ | 0%   | 2022/4/1 |           |     0 |    0    |

本来、エラーがでないはずなのですが、下から、2行目の重複レコードが生じ、開始日非連続にフラグが立ちます。

原因がよく分からず、よろしくお願いいたします。

14
もっちー 2022/04/15 (金) 16:08:18 d73a2@c8d31

すみません、クエリをデザインで開くと(T1.開始日-1=T2.終了日) この部分が消えてしまう?んですかね。
上記のあやまったフラグは出なくなりました。

細かいチェックがまだできていませんが、こちらで恐らく大丈夫なような気がします。

どうもありがとうございました。

15
りんご 2022/04/16 (土) 03:15:30 c564b@0e907

>> 9
 SQLは苦手です。メモさせて下さい。
 原本と原本コピーがあり、原本の開始日をマイナス1、原本コピーの終了日と突合してみたり、原本の終了日をプラス1、原本コピーの開始日と突合してみたり。最終的に左外部結合。原本は一致レコードと不一致レコード、原本コピーは一致レコードとNullレコード。
 そして「T2.終了日 Is Null」と「T3.開始日 Is Null」の部分で不一致クエリ。空欄、先頭の開始日、最後の終了日もひっくるめて判定。
 氏名あああの場合、空欄の不一致判定を除外する為に、「And Not (T1.開始日 Is Null」と「And Not (T2.終了日 Is Null」が必要。
 氏名いいいの場合、先頭の開始日と最後の終了日の不一致判定を除外する為に、「And Not (…T1.開始日 = DMin」と「And Not (…T2.終了日 = DMax」が必要。

16
りんご 2022/04/16 (土) 03:26:31 c564b@0e907

>> 14

細かいチェックがまだできていませんが、こちらで恐らく大丈夫なような気がします。

氏名出向元出向先開始日終了日開始フラグ終了フラグ
りんごAAA店舗12019/4/12020/3/3100
りんごAAA店舗12020/4/12021/3/310?
りんごBBB店舗12021/4/12022/3/31?0
17
もっちー 2022/04/18 (月) 09:23:02 d73a2@c8d31

同姓同名の問題か、転籍等により出向元が変わる場合のことを仰られているのでしょうか。
転籍の場合、手続き上、退職をして入社をするので、氏名が同じでも社員コードが変わり別人格となります。
運用上は、同姓同名の問題もありますので、氏名ではく社員コードで管理をしますので、SQLは読み替えています。
ですので、上記フラグは0で良いです。

18
りんご 2022/04/18 (月) 13:24:13 c564b@0e907

>> 13
>> 16
>> 17

T1からT2, T3に外部結合する際、氏名、出向元、出向先フィールで結合をするように修正し、
 
 出向元フィールドが結合条件に必要か否か気になってしまい、エラー判定が上手く出来ない場合があるかもと思っていました。

演算フィールドのDMin条件には、氏名、出向元、出向先が一対するものと修正いたしました。

 しかし、よくよく見れば、DMinで対応出来ているのでそんな事にはならなかった。

 すみません、視野が狭くなって勘違いしてました。