|
▼チリ子 さん:
一晩寝たら方法を一つ思いつきました。
はじめに、条件が結構面倒なので、クエリの数も増えて
ゴチャゴチャしてしまうことは、御了承下さい。
1.まず、各テーブルをくっつけたユニオンクエリを作ります。
これは、以前の回答(6494)
http://www.vbalab.net/vbaqa/c-board.cgi?cmd=one;no=6494;id=access
の中にあったもので、
これを以後のデータ抽出の基本とします。
SELECT [No], "0504" AS TB, 区分 FROM [0504]
UNION
SELECT [No], "0505" AS TB, 区分 FROM [0505]
UNION
SELECT [No], "0506" AS TB, 区分 FROM [0506];
名前を「Query_union」とします。
2.次にTBの値を連続にしたクエリを作ります。
0504・0505・0506・0507・・・・
と抽出されますが、[No]が"0506"から始まる場合、その[No]は
"0506"以降が抽出されます。
SELECT Qno.[No], Qtb.TB
FROM
(SELECT [No], Min(TB) AS minTB FROM Query_union GROUP BY [No] ) AS Qno,
(SELECT TB FROM Query_union GROUP BY TB ) AS Qtb
WHERE Qtb.TB>=[Qno]![minTB]
ORDER BY Qno.[No], Qtb.TB;
クエリ名を「Query_月TB」として下さい。
あまり、クエリを増やすのもどうかと思ったので、少し端折りました。
「Query_union」を[No]でグループ化し[TB]の最小値を抜出した「Qno」と
「Query_union」を[TB]でグループ化したものをくっつけました。
保存したら、デザインモードや実行結果を確認してください。
3.次は、[No]が欠ける最初の[TB]値を抽出します。
SELECT Query_月TB.[No], Min(Query_月TB.TB) AS TBの最小
FROM Query_月TB LEFT JOIN Query_union ON
(Query_月TB.TB = Query_union.TB) AND
(Query_月TB.[No] = Query_union.[No])
WHERE (Query_union.[No] Is Null)
GROUP BY Query_月TB.[No];
クエリ名は「Query_欠ける最小値」です。
4.次に「Query_union」から集計対象を抽出します。
SELECT Query_union.*
FROM Query_union LEFT JOIN Query_欠ける最小値 ON
Query_union.[No] = Query_欠ける最小値.[No]
WHERE
(
(Query_union.[No] Is Not Null) AND
(Query_union.TB<[Query_欠ける最小値]![TBの最小])
) OR
(Query_欠ける最小値.[No] Is Null)
ORDER BY Query_union.[No], Query_union.TB;
クエリ名を「Query_抽出対象」として下さい。
5.最後に4の「Query_抽出対象」に自作関数「fxMakeGroup」でグループ化
集計すれば完成です。
SELECT [No], 区分, Count(区分) AS カウント
FROM Query_抽出対象
GROUP BY [No], 区分, fxMakeGroup([No],[TB],[区分])
ORDER BY fxMakeGroup([No],[TB],[区分]);
以上です。
簡単なテストしかしてませんので、検証は十分行ってください。
また、ある程度理解できたら、テーブル構造は、「Query_union」と同じになる
ようにする事をお勧めします。
抽出や集計の際の基本となる形であり、以後テーブルの追加があった場合、
そのデータを追加するのみで済み、クエリ等を変更する必要も無くなるので。
あと、フィールド名の[No]もYes/NoのNoと混同され易く、後のトラブルの
原因にもなりかねないので変更されることをお勧めします。
|
|