質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.53%

  • MySQL

    5834questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

subqueryのorder byを効かすには

受付中

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 139

takagi.1994

score 36

やりたいことは、
tableAtableBとは1対nの関係で結合させて
tableB.cdの降順, tableA.idの昇順で取得したい。
また、条件によってtableB.cdで降順したtableB最初の1件の場合と全件が必要です。

tableAはマスターでtableBにデータがあるデータが蓄積されcdの値が増えていきます。
よって、値が大きいものが最新となります。
取得する際はtableaに対してソートをしてもその際のtableBのデータは最新順(つまり降順)とさせたい。
また、条件(最新の1件のみのflagがあるない)によってtableBから取得するデータを1件or全件としたい。

SELECT *
FROM `tableA`
LEFT JOIN `tableB`
ON `tableA`.`id` = `tableB`.id
GROUP BY `tableA`.`id`
ORDER BY `tableA`.`id` ASC, `tableB`.`cd` DESC
SELECT *
FROM (
    SELECT *
    FROM `tableA`
    LEFT JOIN `tableB`
    ON `tableA`.`id` = `tableB`.id
    ORDER BY `tableB`.`cd` DESC
) as `tableC`
GROUP BY `tableC`.`id`
ORDER BY `tableC`.`cd` ASC


こんな感じで試してみたのですがうまくいきません。

うまく行く方法はありますでしょうか?

CREATE TABLE `tablea` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `customerName` varchar(60) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

CREATE TABLE `tableb` (
  `cd` int(11) NOT NULL AUTO_INCREMENT,
  `id` int(11) NOT NULL,
  `data1` varchar(255) NOT NULL,
  PRIMARY KEY (`cd`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

INSERT INTO `tablea` (`id`, `customerName`) VALUES
(1, 'aaaa'),
(2, 'bbbb'),
(3, 'cccc');
(4, 'dddd');

INSERT INTO `tableb` (`cd`, `id`, `data1`) VALUES
(1, 1, 'hoge11'),
(2, 1, 'hoge12'),
(3, 1, 'hoge13'),
(4, 2, 'hoge21'),
(5, 2, 'hoge22'),
(6, 2, 'hoge22'),
(7, 3, 'hoge31');

期待する結果1

id    customerName    cd    id1    data1
1    aaaa        3    1    hoge13
1    aaaa        2    1    hoge12
1    aaaa        1    1    hoge11
2    bbbb        6    2    hoge23
2    bbbb        5    2    hoge22
2    bbbb        4    2    hoge21
3    cccc        7    3    hoge31
4    dddd        null    null    null

期待する結果2

id    customerName    cd    id1    data1
1    aaaa        3    1    hoge13
2    bbbb        6    2    hoge23
3    cccc        7    3    hoge31
4    dddd        null    null    null

UI側で"最新のみ"のチェックボックスがあるのでそれにチェックがあるかないかによって
期待する結果は1と2に分かれます。

また、プログラム側でwhere区をUI側で選択されたその他の条件で組み立てて行くつもりですが、
今回はそこは問題になってはいません。

最新flagがあるかないかで基本的なsql分は分けたくないなと思っています。
where区を組み立てるロジックをできればそれぞれに書きたくない。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Kosuke_Shibuya

    2018/06/22 00:51

    この手の質問では、CREATE文でテーブルの定義、サンプルデータのINSERT文を提示してくれると手元の環境でサクッと試して確度の高い回答を提示できますが、それがないと、質問文んを読み込んでいちいちテーブル定義から書き起こす必要があります。精度の高い回答を求める場合は、定義およびデータを提示してほしい。

    キャンセル

  • takagi.1994

    2018/06/22 01:33

    大変失礼しました。追記いたしました。

    キャンセル

回答 3

0

SUBQUERYにする必要がわかりません。

CREATE TABLE文が提示されたのでSELECT文を訂正しました。

SELECT DISTINCT
    B.`cd`
   ,A.`id`
  , A.`customerName`
  , B.`data1`
FROM `tableA` A
LEFT JOIN `tableB` B
ON A.`id` = B.`id`
ORDER BY B.`cd` DESC, A.`id`

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/22 01:32

    早速のご回答ありがとうございます。

    試してみましたが、`tablea`.`id` ASCが効かないようです。
    また、この場合、tableB.cdの全件は取得できても降順の最初の1件のみが取得できません。

    キャンセル

  • 2018/06/22 02:15

    CREATE TABLE文が提示されたのでSELECT文を訂正しました。

    キャンセル

  • 2018/06/22 02:23

    group by A.idをつけるとb.cdが昇順となってしまい、期待する値(最新)ではなくなってしまいます。

    キャンセル

  • 2018/06/22 02:42

    group byではなくDISTINCTにしました。
    どんな出力結果が欲しいのか「質問」に追加しては?

    キャンセル

0

どんな結果を想定しているのか見えてきませんが、
単にcdとidのソート順が違うだけでは?

select * from tableA as t1
inner join tableB as t2 on t1.id=t2.id
order by t1.id asc,t2.cd desc

 追記

もしcdの最大値だけとってid順に表示したということであればこう

select * from tableA as t1
inner join tableB as t2 on t1.id=t2.id
where not exists(select 1 from tableB where id=t2.id and cd>t2.cd)
order by t2.id asc

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

「同じIDで登録されたものの内の最新のCDのデータ」というを解釈しました。
相関副問合せで、同じIDで最大のCDを条件とします

select * 
from tableb as tb left join tablea as ta
     on tb.id=ta.id
where not exists(select 1 from tableb where id=tb.id and cd > tb.cd)
order by tb.id, tb.cd

 
または

select * 
from tableb as tb left join tablea as ta
     on tb.id=ta.id
where tb.cd=(select max(cd) from tableb where id = tb.id)
order by tb.id, tb.cd

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/22 10:01

    existsの後ろに余計な「=」が・・・

    キャンセル

  • 2018/06/22 10:05

    あ、ホントだ。コピーして書き換えたから・・
    指摘ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.53%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • MySQL

    5834questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。