MySQLのcount取得時、グループごとに日付降順でカウンタ値と外部結合のデータを取得する方法
解決済
回答 2
投稿
- 評価
- クリップ 0
- VIEW 1,311
MySQL におけるデータ取得で悩んでいる箇所があります。
簡略化すると、次のような構成のテーブルがあります。
●テーブルA(データ本体)
|DATA_ID|CAT_ID|START_TIME|
|1|1|2016-04-01 14:00:00|
|2|1|2016-04-01 13:25:00|
|3|1|2016-04-01 15:10:00|
|4|2|2016-04-01 15:00:00|
●テーブルB(カテゴリマスタ)
|CAT_ID|CAT_SUB_ID|NAME|
|1|test1|テスト1|
|2|test2|テスト2|
●得たい結果
|COUNTER|DATA_ID|START_TIME|CAT_ID|CAT_SUB_ID|
|1|3|2016-04-01 15:10:00|1|test1|
|1|4|2016-04-01 15:00:00|2|test2|
|2|1|2016-04-01 14:00:00|1|test1|
|3|2|2016-04-01 13:25:00|1|test1|
START_TIME列でDESCした上で、CAT_IDでグループ化された結果に対して逆順でカウンタ値を生成し、テーブルBのデータを取得する、というのが行いことになります。
●試した結果
SELECT (SELECT COUNT(*)+1 FROM tblA as T2 LEFT JOIN tblB on T2.CAT_ID = tblB.CAT_ID WHERE T2.START_DATE < T1.START_DATE and T2.CAT_ID = T1.CAT_ID and T2.START_DATE < "実行時刻" ORDER BY T2.START_DATE DESC ) AS counter , T1.* FROM tblA AS T1 where T1.VIEW = 'TRUE' and T1.START_DATE < "実行時刻" ORDER BY T1.START_DATE DESC
●得られた結果
|COUNTER|DATA_ID|START_TIME|CAT_ID|CAT_SUB_ID|
|3|3|2016-04-01 15:10:00|--|--|
|1|4|2016-04-01 15:00:00|--|--|
|2|1|2016-04-01 14:00:00|--|--|
|1|2|2016-04-01 13:25:00|--|--|
●質問内容
こちら、上記の件を解決させたいのが第一なのですが、今後の為に次の点も教えていただけると助かります。
1)MySQLにおける、countの実行タイミング(上記の結果を見ると、WHERE句の実行時という認識で大丈夫でしょうか?)
2)サブクエリ実行時は、外部結合が使用できない? それとも上記の記述がまずい?
よろしくお願いいたします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
SELECT
(
SELECT COUNT(*)+1 FROM tblA as T2
WHERE T1.START_TIME < T2.START_TIME
AND T2.CAT_ID = T1.CAT_ID
) AS counter
, T1.* ,T3.CAT_SUB_ID
FROM tblA AS T1
LEFT JOIN tblB T3 ON T2.CAT_ID = T3.CAT_ID
ORDER BY T1.START_TIME DESC
動作確認はしていませんがこんな感じでしょうか?
やってみたSQLにはサンプルテーブルに無い要素がありましたが、サンプルテーブルデータのほうに合わせたコードにしています。
1)MySQLにおける、countの実行タイミング
そのクエリ内のほかの句を実行した後です。
2)サブクエリ実行時は、外部結合が使用できない?
できます。やってみたSQLでは、最初のサブクエリでcount(*)+1しか出力していないので、何を結合しても出力されるのはカウントだけだったということになります。
※そもそもselect句内のサブクエリで複数項目出力はできなかったように思います。(自信無い)
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
こちら、降順での連番付与、自己解決いたしました。完全にハマっていたところ、hirohiroさんのヒントにより解決いたしました、本当にありがとうございます。
SELECT
(
SELECT COUNT(T2.START_TIME)+1 FROM tblA as T2
WHERE T1.START_TIME < T2.START_TIME
AND T1.CAT_ID = T2.CAT_ID
) AS counter
, T1.* ,T3.CAT_SUB_ID
FROM tblA AS T1
LEFT JOIN tblB T3 ON T2.CAT_ID = T3.CAT_ID
ORDER BY T1.START_TIME DESC
カウント取得用のサブクエリで、
1)全件取得ではなく、降順取得したい列名を指定
2)サブクエリ中のWHERE 句照合対象を逆に(T1.T2ひっくり返した)
3)本クエリでSTART_TIMEをDESC
hirohiroさん並びに、閲覧していただいた方々、ありがとうございます。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 89.99%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/04/04 21:00
(2)
こちら、例示いただいたSQL文を見てはっとしましたが、あまりにもハマりすぎて、完全に基本的な部分が抜け落ちておりました…。
あまりにも基本的でお恥ずかしいほど…。
いただいた回答をもとに打ってみたところ、tblB側からのデータは当然ですが成功いたしました。ありがとうございます。
カウント値がやはり、START_TIMEの古い方から付番されており、後はこの点を解決できれば…というところです。
2016/04/04 21:06
ああ、サブクエリのWhere句の条件が逆でしたね。
修正しておきました。
WHERE T2.START_TIME < T1.START_TIME → WHERE T1.START_TIME < T2.START_TIME