こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Accessのsql(ロジック)について伺います

Access mdb内でローカルDB(ADO)へSQL接続を行うプログラムを組んでおります。

■テーブル:マスタTBL
| 年 | 月 | 日 | 時 | 分 | 秒 | コード |
+---- +-- +-- +-- +--+---+------+
| 2013 | 10 | 31 | 10 | 05 | 20 | A1234 |
| 2013 | 10 | 31 | 10 | 10 | 00 | B1234 |
| 2013 | 11 | 01 | 00 | 00 | 01 | A1234 |
| 2013 | 11 | 01 | 00 | 00 | 01 | A1234 |
| 2013 | 11 | 01 | 00 | 00 | 01 | A1234 |
| 2013 | 11 | 22 | 05 | 10 | 09 | C1234 |
| 2013 | 10 | 31 | 00 | 10 | 00 | B1234 |
| 2013 | 10 | 31 | 22 | 46 | 55 | A1234 |

※後の作業都合上、日付も含めカラムは全て"文字列"です。
※全カラム、nullは存在しません。
※各レコードの格納順に統一性はありません。
※動作環境はAccess mdb(Office 2007)/Windows7(32bit)です。

【最終的にやりたいこと】
マスタTBLより、最繁日3日分(同じ年月日のレコード数が多い上位3日分)を選定し、
更に時間別、かつコード別の件数を求める(.csv出力)のが最終目標です。
SQL一発でできれば良いのですが、私の力ではそれが組めないため2段階に分け、
第1段階として別の作業用TBLを作成し、まずそこに最繁日3日分を抽出&登録、
第2段階で作業用TBLに対して時間別・コード単位の抽出を行う段取りとしました。
ご質問は、第1段階を満たすSQLについてです。


【ご質問】
上記のテーブルがあるとします。
この中から、最繁日3日分(同じ年月日(時分秒は考慮不要)のレコード数が多い上位3日分)の全レコード(抽出には時分秒も必要)を抽出し、同設定の別テーブルへ登録したい。
と言うのがやりたい事なのですが、抽出するSQLが作れず困っております。
現group by設定をしてしまうと、Countさせて上位日数と件数は判明できますが、その全レコードを羅列させる事ができません。
抽出段階で考慮すべきは日付までなので、group byを考えて時分秒を省いてしまうと、その後秒単位で抽出が必要な第2段階が行えなくなってしまいます。
また時分秒をSELECTに指定してしまうと、group byでも時分秒を加えなくてはいけなくなり、「日付3日分で」が満たされなくなってしまいます。。。

現在、group by有りで作成済みのSQL、および出力結果例は下記の通りで、
全く先に進まなくなってしまいました....
[SQL]
'SQL作成
変数A = "INSERT INTO 登録したいTBL " _
& "SELECT 年,月,日,時,分,秒,コード,COUNT(*) AS CNT " _
& "FROM マスタTBL " _
& "group by 年,月,日,時,分,秒,コード " _
& "order by 年,月,日,時,分,秒,コード;"

'SQL実行
Call db.Execute(変数A)


[実行結果例]
■テーブル:登録したいTBL
| 年 | 月 | 日 | 時 | 分 | 秒 | コード | カウント |
+---- +-- +-- +- -+- -+-- +----- +-------+
| 2013 | 10 | 31 | 10 | 05 | 20 | A1234 | 2 |
| 2013 | 10 | 31 | 10 | 10 | 00 | B1234 | 2 |
| 2013 | 11 | 01 | 00 | 00 | 01 | A1234 | 3 |
| 2013 | 11 | 22 | 05 | 10 | 09 | C1234 | 1 |


現状では当然の出力結果ですが、本来出力したいのは、カウントが3件の3レコードと、
2件のレコード*2つ、合計7レコードを出力させたいと言う意味です。
(カウントは必要かと思ったので入れているだけで、仕様上は別に無くても良い物です。)
また、とりあえずですが上記SQLが正しく実行され登録したいTBLへ格納される事は確認済みです。


やり方がそもそも間違えている可能性もございますので、その点も含めご指摘ございましたらお願い致します。


以上です。
ご提示できる条件が少なく申し訳ございませんが、ご回答頂ける方がいましたら、
ご教授をよろしくお願い致します。

投稿日時 - 2013-11-07 21:03:54

QNo.8338317

すぐに回答ほしいです

質問者が選んだベストアンサー

こういうことですか?
オリジナルテーブル名を、T1 としています。
SELECT TOP 3 年, 月, 日, コード, count(*) AS cnt
FROM T1
GROUP BY 年, 月, 日, コード
ORDER BY count(*) DESC;
で上位3位まで取り出します。
ただし、『同値のcount(*) AS cnt が多い場合』は
3件よりも多くなります。

このクエリを Q1 として、
SELECT T1.年, T1.月, T1.日, T1.時, T1.分, T1.秒, T1.[コード], Q1.cnt
FROM T1
INNER JOIN Q1
ON (T1.[コード] = Q1.[コード]) AND (T1.日 = Q1.日) AND (T1.月 = Q1.月) AND (T1.年 = Q1.年);
としてみると?

一つにまとめると
T1_out テーブルが、年、月、日、時、分、秒、コード、cnt フィールドで用意されていたら

INSERT INTO T1_out
SELECT [T1].年 AS 年, [T1].月 AS 月, [T1].日 AS 日, [T1].時 AS 時, [T1].分 AS 分, [T1].秒 AS 秒, [T1].[コード] AS コード, QX.cnt AS cnt
FROM T1
INNER JOIN
(SELECT TOP 3 年, 月, 日, [コード], count(*) AS cnt FROM T1 GROUP BY 年, 月, 日, [コード] ORDER BY count(*) DESC) AS QX
ON ([T1].[コード]=QX.[コード]) AND ([T1].日=QX.日) AND ([T1].月=QX.月) AND ([T1].年=QX.年);

かな?
テスト環境でお試しを。

投稿日時 - 2013-11-08 12:12:10

お礼

ご回答ありがとうございました。
もう半年も前にご丁寧なご回答を頂いたにも関わらず、諸事情によりお礼ができずに申し訳ございませんでした。

投稿日時 - 2014-06-11 00:58:20

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

-広告-
-広告-

回答(2)

ANo.1

サブクエリ+Topキーワードでどうでしょう?
試験環境が手元にないので、まずはSelectのみ行って試験してください。

select 年, 月, 日, 時, 分, 秒, コード, count(*) カウント
FROM マスタTBL
where (年 & 月 & 日) in
(
 select top 3 年 & 月 & 日 年月日, count(*) カウント
 FROM マスタTBL
 gropu by 年月日
 order by カウント desc
)
group by 年, 月, 日, 時, 分, 秒, コード
order by 年, 月, 日, 時, 分, 秒, コード
;

投稿日時 - 2013-11-07 21:50:50

-広告-
-広告-

あなたにオススメの質問

-広告-
-広告-