工場の作業現場でマシンを追跡する Access データベースがあります。私が使用している2つのテーブルがあります:
marstable
- 各マシンが完了した操作のリストstatustable
- マシンのステータス変更のリスト
marstable
には約 100,000 のエントリがありますがstatustable
、100 未満です。
次の 3 つのいずれかを見つけるには、一度に 1 台のマシンを検索する必要があります。
- マシンが両方のテーブルにエントリを持っている場合は、両方からデータを返します。
- マシンにエントリしかない場合は、
marstable
そのテーブルからデータを返します。 - マシンのエントリが にしかない場合は、そのエントリ
statustable
からデータを返します。
これを達成するために SQL クエリを実行するにはどうすればよいですか? statustable
現在、左結合を使用すると、 (左結合の「右」部分) に データしかない場合を除いて機能します。
marstable
トランザクションの時系列リストで、次のようになります。
+--------+----------+-----------+----------+-----------------------+
| order | machine | operation | quantity | insertdate |
+--------+----------+-----------+----------+-----------------------+
| 12345 | A10 | 110 | 2339 | 11/16/2012 9:57:15 AM |
| 67890 | B11 | 450 | 10330 | 11/16/2012 9:15:03 AM |
+--------+----------+-----------+----------+-----------------------+
statustable
マシンの状態変化の時系列リストです。次のようになります。
+---------+--------+-----------------------+--------+
| machine | status | inserttime | note |
+---------+--------+-----------------------+--------+
| A10 | 6 | 11/5/2012 10:52:22 AM | broken |
| J90 | 7 | 11/9/2012 12:48:46 PM | robot |
+---------+--------+-----------------------+--------+
私が使用しているSQLクエリは次のようになります。
SELECT TOP 1 [machine], [quantity], [order], [operation], [insertdate], [status], [inserttime], [note]
FROM [marstable] LEFT JOIN [statustable] ON [marstable].[machine] = [statustable].[machine]
WHERE [marstable].[machine] = '<<machine I want get's passed in here>>'
ORDER BY [marstable].[insertdate] DESC, [statustable].[inserttime] DESC
問題は、にエントリが存在しないのに にエントリがある場合、marstable
まだ何も得られないことです。statustable
よろしくお願いいたします。また、テーブルがどのように見えるかを制御することはできません。
最後に、上記の表に対する ascii-art スキルが不足していることをご容赦ください。
更新#1:
以下の彼の回答の1つから@Olivierのサブクエリソリューションを実装しようとしています。ただし、それを行うと、エラーが発生します too few parameters. Expected 2.
私の実装は、パラメーターを要求する代わりに、マシン ID を SQL を生成する関数に渡すという点で彼とは異なります。
SQLはこのように生成されます
MarsSQL = _
"SELECT M.msg_machine, M.msg_qtyorstatus, M.msg_entity, M.msg_operation, M.msg_creator, M.msg_insertdate, " & _
"S.Machine, S.Status, S.InsertTime, S.Note, S.UserID " & _
"FROM " & _
"(SELECT TOP 1 msg_machine, msg_qtyorstatus, msg_entity, msg_operation, msg_creator " & _
"FROM MARSTable WHERE msg_machine = '" & "00" & fMachine & "' ORDER BY msg_insertdate DESC" & _
") M, " & _
"(SELECT TOP 1 Machine, Status, InsertTime, Note " & _
"FROM StatusTable WHERE Machine = '" & fMachine & "' ORDER BY InsertTime DESC" & _
") S;"
fMachine
現在探しているマシンを保持する文字列です。最終結果は、SQL が次のようになることです (マシン A10 の場合)。
SELECT M.msg_machine, M.msg_qtyorstatus, M.msg_entity, M.msg_operation, M.msg_creator, M.msg_insertdate,
S.Machine, S.Status, S.InsertTime, S.Note, S.UserID
FROM
(SELECT TOP 1 msg_machine, msg_qtyorstatus, msg_entity, msg_operation, msg_creator
FROM MARSTable WHERE msg_machine = '00A10' ORDER BY msg_insertdate DESC
) M,
(SELECT TOP 1 Machine, Status, InsertTime, Note
FROM StatusTable WHERE Machine = 'A10' ORDER BY InsertTime DESC
) S;
注:最初の例では単純化されたテーブルを使用していましたが、この SQL は私が生成した実際の SQL です。 また、各フィールド/テーブルを囲む [角括弧] の有無にかかわらずこれを試しましたが、違いはありません。
更新 #2: 2 番目のサブクエリのフィールドがありませんでした。私はそれを追加しましたが、同じエラーが表示されますが、 2ではなく1つのパラメーター。これで、SQL は次のようになります。
SELECT M.msg_machine, M.msg_qtyorstatus, M.msg_entity, M.msg_operation, M.msg_creator, M.msg_insertdate,
S.Machine, S.Status, S.InsertTime, S.Note, S.UserID
FROM
(SELECT TOP 1 msg_machine, msg_qtyorstatus, msg_entity, msg_operation, msg_creator
FROM MARSTable WHERE msg_machine = '00A10' ORDER BY msg_insertdate DESC
) M,
(SELECT TOP 1 Machine, Status, InsertTime, Note, UserID
FROM StatusTable WHERE Machine = 'A10' ORDER BY InsertTime DESC
) S;
UserID
2 番目のサブクエリで欠落していたフィールドです。
解決済み:最初のサブクエリから別のフィールドが欠落していました。それを片付けたら、解決策はうまくいきました。SQL は次のようになります。
SELECT M.msg_machine, M.msg_qtyorstatus, M.msg_entity, M.msg_operation, M.msg_creator, M.msg_insertdate,
S.Machine, S.Status, S.InsertTime, S.Note, S.UserID
FROM
(SELECT TOP 1 msg_machine, msg_qtyorstatus, msg_entity, msg_operation, msg_creator, msg_insertdate
FROM MARSTable WHERE msg_machine = '00A10' ORDER BY msg_insertdate DESC
) M,
(SELECT TOP 1 Machine, Status, InsertTime, Note
FROM StatusTable WHERE Machine = 'A10' ORDER BY InsertTime DESC
) S;
ここで助けてくれたみんなに感謝します。