SQL サブクエリ
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2022/8/3 11:59:30
CREATE TABLE [テーブルA] ([ID] CHAR(3) PRIMARY KEY, [検査日1] DATE, [検査日2] DATE, [検査日3] DATE);
INSERT INTO [テーブルA] ([ID], [検査日1], [検査日2], [検査日3]) VALUES ( '001', #5/10/2021#, #12/20/2021#, #3/5/2022#);
INSERT INTO [テーブルA] ([ID], [検査日1], [検査日2], [検査日3]) VALUES ( '002', #6/13/2021#, #5/20/2022#, NULL);
INSERT INTO [テーブルA] ([ID], [検査日1], [検査日2], [検査日3]) VALUES ( '003', #1/30/2021#, #8/1/2022#, NULL);
INSERT INTO [テーブルA] ([ID], [検査日1], [検査日2], [検査日3]) VALUES ( '004', #8/5/2021#, NULL, NULL);
INSERT INTO [テーブルA] ([ID], [検査日1], [検査日2], [検査日3]) VALUES ( '005', #3/10/2021#, #11/1/2021#, #2/8/2022#);
---
PARAMETERS [スタート日付] DATE, [エンド日付] DATE;
SELECT [ID], [検査日1] AS [検査日], '検査日1' AS [列名] FROM [テーブルA] WHERE [検査日1] >= [スタート日付] AND [検査日1] <= [エンド日付]
UNION ALL
SELECT [ID], [検査日2] AS [検査日], '検査日2' AS [列名] FROM [テーブルA] WHERE [検査日2] >= [スタート日付] AND [検査日2] <= [エンド日付]
UNION ALL
SELECT [ID], [検査日3] AS [検査日], '検査日3' AS [列名] FROM [テーブルA] WHERE [検査日3] >= [スタート日付] AND [検査日3] <= [エンド日付]
ORDER BY 2, 1;
INSERT INTO [テーブルA] ([ID], [検査日1], [検査日2], [検査日3]) VALUES ( '001', #5/10/2021#, #12/20/2021#, #3/5/2022#);
INSERT INTO [テーブルA] ([ID], [検査日1], [検査日2], [検査日3]) VALUES ( '002', #6/13/2021#, #5/20/2022#, NULL);
INSERT INTO [テーブルA] ([ID], [検査日1], [検査日2], [検査日3]) VALUES ( '003', #1/30/2021#, #8/1/2022#, NULL);
INSERT INTO [テーブルA] ([ID], [検査日1], [検査日2], [検査日3]) VALUES ( '004', #8/5/2021#, NULL, NULL);
INSERT INTO [テーブルA] ([ID], [検査日1], [検査日2], [検査日3]) VALUES ( '005', #3/10/2021#, #11/1/2021#, #2/8/2022#);
---
PARAMETERS [スタート日付] DATE, [エンド日付] DATE;
SELECT [ID], [検査日1] AS [検査日], '検査日1' AS [列名] FROM [テーブルA] WHERE [検査日1] >= [スタート日付] AND [検査日1] <= [エンド日付]
UNION ALL
SELECT [ID], [検査日2] AS [検査日], '検査日2' AS [列名] FROM [テーブルA] WHERE [検査日2] >= [スタート日付] AND [検査日2] <= [エンド日付]
UNION ALL
SELECT [ID], [検査日3] AS [検査日], '検査日3' AS [列名] FROM [テーブルA] WHERE [検査日3] >= [スタート日付] AND [検査日3] <= [エンド日付]
ORDER BY 2, 1;
PARAMETERS 句を使ったクエリにするかどうかはお好みで。
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/parameters-declaration-microsoft-access-sql
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2022/8/3 12:04:46
> INSERT INTO [テーブルA] ([ID], [検査日1], [検査日2], [検査日3]) VALUES ( '003', #1/30/2021#, #8/1/2022#, NULL);
失礼しました。元データは
INSERT INTO [テーブルA] ([ID], [検査日1], [検査日2], [検査日3]) VALUES ( '003', #1/30/2022#, #8/1/2022#, NULL);
でしたね。
横に「列」として並んでいるデータを縦積みにするなら、UNION クエリ
縦に「行」として並んでいるデータを横積みにするなら、TRANSFORM クエリ
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/union-operation-microsoft-access-sql
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/transform-statement-microsoft-access-sql
失礼しました。元データは
INSERT INTO [テーブルA] ([ID], [検査日1], [検査日2], [検査日3]) VALUES ( '003', #1/30/2022#, #8/1/2022#, NULL);
でしたね。
横に「列」として並んでいるデータを縦積みにするなら、UNION クエリ
縦に「行」として並んでいるデータを横積みにするなら、TRANSFORM クエリ
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/union-operation-microsoft-access-sql
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/transform-statement-microsoft-access-sql
投稿者 はなな  (社会人)
投稿日時
2022/8/3 15:44:14
魔界の仮面弁士さん、ありがとうございます。
いただいたコードであっという間に欲しいデータが取得できました!
>SELECT [ID], [検査日1] AS [検査日], '検査日1' AS [列名] FROM [テーブルA] WHERE [検査日1] >= >[スタート日付] AND [検査日1] <= [エンド日付]
>UNION ALL
>SELECT [ID], [検査日2] AS [検査日], '検査日2' AS [列名] FROM [テーブルA] WHERE [検査日2] >= >[スタート日付] AND [検査日2] <= [エンド日付]
>UNION ALL
>SELECT [ID], [検査日3] AS [検査日], '検査日3' AS [列名] FROM [テーブルA] WHERE [検査日3] >= >[スタート日付] AND [検査日3] <= [エンド日付]
>ORDER BY 2, 1;
ですが...
なぜか日付の範囲指定を入れるとエラーになってしまいます。
午後ずっと苦戦しております。
ORDER BYは
ORDER BY [検査日], [ID]
上記でうまくいきました。
[スタート日付]と[エンド日付]はDATEタイプで取ってあります。
[検査日1] [検査日2] [検査日3]は日付/時刻型です。
[検査日1] >= [スタート日付]
[検査日1] >= '[スタート日付]'
[検査日1] >= "[スタート日付]"
などと試してみましたが駄目でした。
[検査日1] を[検査日]としても駄目でした。
何がいけないのでしょうか。
初心者が間違っていそうなところはありますでしょうか?
何度も恐れ入りますが、よろしくお願い致します。
いただいたコードであっという間に欲しいデータが取得できました!
>SELECT [ID], [検査日1] AS [検査日], '検査日1' AS [列名] FROM [テーブルA] WHERE [検査日1] >= >[スタート日付] AND [検査日1] <= [エンド日付]
>UNION ALL
>SELECT [ID], [検査日2] AS [検査日], '検査日2' AS [列名] FROM [テーブルA] WHERE [検査日2] >= >[スタート日付] AND [検査日2] <= [エンド日付]
>UNION ALL
>SELECT [ID], [検査日3] AS [検査日], '検査日3' AS [列名] FROM [テーブルA] WHERE [検査日3] >= >[スタート日付] AND [検査日3] <= [エンド日付]
>ORDER BY 2, 1;
ですが...
なぜか日付の範囲指定を入れるとエラーになってしまいます。
午後ずっと苦戦しております。
ORDER BYは
ORDER BY [検査日], [ID]
上記でうまくいきました。
[スタート日付]と[エンド日付]はDATEタイプで取ってあります。
[検査日1] [検査日2] [検査日3]は日付/時刻型です。
[検査日1] >= [スタート日付]
[検査日1] >= '[スタート日付]'
[検査日1] >= "[スタート日付]"
などと試してみましたが駄目でした。
[検査日1] を[検査日]としても駄目でした。
何がいけないのでしょうか。
初心者が間違っていそうなところはありますでしょうか?
何度も恐れ入りますが、よろしくお願い致します。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2022/8/3 16:35:05
> WHERE [検査日1] >= >[スタート日付] AND
「>」の指定が不自然なのは、返信時のミスでしょうか。
> なぜか日付の範囲指定を入れるとエラーになってしまいます。
せめて、何というエラーになるのかぐらいは教えてくださいな…。😅
エラーメッセージを写す際には、一字一句正確に。
> なぜか日付の範囲指定を入れるとエラーになってしまいます。
VB6 なのですよね。mdb への接続は何で行っていますか?
①DAO 3.x (Microsoft Data Access Objects Library)
②ACEDAO (Microsoft Office Access Databese Engine Object Library)
③ADO (Microsoft ActiveX Data Objects Library) + JET Provider
④ADO (Microsoft ActiveX Data Objects Library) + ACE Provider
⑤その他 (RDO など)
日付値を SQL 文字列内に直接埋め込む場合は
WHERE [検査日1] >= #8/1/2021# AND [検査日1] <= #3/11/2022#
のように記述します。日付リテラルは mm/dd/yyyy の順で並べ、両端を # で囲みます。
https://support.microsoft.com/ja-jp/office/access-%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%A7%E6%8A%BD%E5%87%BA%E6%9D%A1%E4%BB%B6%E3%81%A8%E3%81%97%E3%81%A6%E6%97%A5%E4%BB%98%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E4%BE%8B-aea83b3b-46eb-43dd-8689-5fc961f21762#__toc358028377
日付をパラメータークエリとする場合、
①②では QueryDef オブジェクトの Parameters プロパティから指定します。
③④では Command オブジェクトの Parameters プロパティから指定します。
https://selifelog.com/blog-entry-159.html
ADO 利用時に、.Parameters.Refresh でパラメーターを自動取得できない場合は、
.Parameters.Append を使ってパラメーターを追加してみてください。
「>」の指定が不自然なのは、返信時のミスでしょうか。
> なぜか日付の範囲指定を入れるとエラーになってしまいます。
せめて、何というエラーになるのかぐらいは教えてくださいな…。😅
エラーメッセージを写す際には、一字一句正確に。
> なぜか日付の範囲指定を入れるとエラーになってしまいます。
VB6 なのですよね。mdb への接続は何で行っていますか?
①DAO 3.x (Microsoft Data Access Objects Library)
②ACEDAO (Microsoft Office Access Databese Engine Object Library)
③ADO (Microsoft ActiveX Data Objects Library) + JET Provider
④ADO (Microsoft ActiveX Data Objects Library) + ACE Provider
⑤その他 (RDO など)
日付値を SQL 文字列内に直接埋め込む場合は
WHERE [検査日1] >= #8/1/2021# AND [検査日1] <= #3/11/2022#
のように記述します。日付リテラルは mm/dd/yyyy の順で並べ、両端を # で囲みます。
https://support.microsoft.com/ja-jp/office/access-%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%A7%E6%8A%BD%E5%87%BA%E6%9D%A1%E4%BB%B6%E3%81%A8%E3%81%97%E3%81%A6%E6%97%A5%E4%BB%98%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E4%BE%8B-aea83b3b-46eb-43dd-8689-5fc961f21762#__toc358028377
日付をパラメータークエリとする場合、
①②では QueryDef オブジェクトの Parameters プロパティから指定します。
③④では Command オブジェクトの Parameters プロパティから指定します。
https://selifelog.com/blog-entry-159.html
Dim query As DAO.QueryDef, rs As DAO.Recordset
Set query = db.CreateQueryDef("", SQL)
cmd.Parameters("スタート日付").Value = #8/1/2021#
cmd.Parameters("エンド日付").Value = #3/11/2022#
Set rs = query.OpenRecordset(dbOpenDynaset)
Dim cmd As ADODB.Command, rs As ADODB.Recordset
Set cmd = New ADODB.Command
Set cmd.ActiveConnection = cn
cmd.CommandText = SQL
cmd.Parameters.Refresh
cmd.Parameters(0).Value = #8/1/2021#
cmd.Parameters(1).Value = #3/11/2022#
Set rs = cmd.Execute
ADO 利用時に、.Parameters.Refresh でパラメーターを自動取得できない場合は、
.Parameters.Append を使ってパラメーターを追加してみてください。
投稿者 はなな  (社会人)
投稿日時
2022/8/4 14:21:46
魔界の仮面弁士さん、ありがとうございます。
返信が遅くなり申し訳ありません。
>> WHERE [検査日1] >= >[スタート日付] AND
>「>」の指定が不自然なのは、返信時のミスでしょうか。
すみません、ミスのようです。
>> なぜか日付の範囲指定を入れるとエラーになってしまいます。
>せめて、何というエラーになるのかぐらいは教えてくださいな…。😅
>エラーメッセージを写す際には、一字一句正確に。
本当にすみません、そうですよね、エラーが何かも記載せずに投稿してしまいました。
今度質問する時にはきちんと記載させていただきます。
MDBへの接続は①のDAOで行っています。
また、日付値はSQLに直接埋め込んでいます。
そして、教えて頂いたように「#」で両端を囲んだらうまくいきました!
色々なパターンの説明もいただきありがとうございました。
勉強不足で申し訳なかったのですが、本当に助かりました。
ありがとうございました。
返信が遅くなり申し訳ありません。
>> WHERE [検査日1] >= >[スタート日付] AND
>「>」の指定が不自然なのは、返信時のミスでしょうか。
すみません、ミスのようです。
>> なぜか日付の範囲指定を入れるとエラーになってしまいます。
>せめて、何というエラーになるのかぐらいは教えてくださいな…。😅
>エラーメッセージを写す際には、一字一句正確に。
本当にすみません、そうですよね、エラーが何かも記載せずに投稿してしまいました。
今度質問する時にはきちんと記載させていただきます。
MDBへの接続は①のDAOで行っています。
また、日付値はSQLに直接埋め込んでいます。
そして、教えて頂いたように「#」で両端を囲んだらうまくいきました!
色々なパターンの説明もいただきありがとうございました。
勉強不足で申し訳なかったのですが、本当に助かりました。
ありがとうございました。
VB6 MDB
下記のようなテーブル(テーブルA)のデータを日付の範囲指定(条件)によって抽出したいです。
まず検査日1が条件にあうもの。
次に検査日2が条件にあうもの。
そして最後に検査日3が条件にあうもの。
抽出データは、ID、検査日、検査日の種類
抽出順は検査日昇順
テーブルA
ID、検査日1、検査日2、検査日3
001、2021/05/10、2021/12/20、2022/03/05
002、2021/06/13、2022/05/20、
003、2022/01/30、2022/08/01、
004、2021/08/05、 、
005、2021/03/10、2021/11/01、2022/02/08
条件:2021/08/01~2022/03/01
抽出データ(検査日順)
004、2021/08/05、検査日1
005、2021/11/01、検査日2
001、2021/12/20、検査日2
003、2022/01/30、検査日1
005、2022/02/08、検査日3
検査日1だけのSQL文は出来るのですが、そこに検査日2と検査日3を紐づけられません。
SELECT ID, 検査日1 AS 検査日, 検査日の種類
FROM テーブルA
WHERE 検査日1>= スタート日付 AND 検査日1 <= エンド日付
ORDER BY 検査日
サブクエリやJOINを使用するということは分かるのですが
それをSQL文にすることが出来ません。
初歩的な質問なのは重々承知しておりますが、どのようにSQL文を組み立てればいいのか教えて下さい。
どうぞよろしくお願い致します。