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

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

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

4回答

1606閲覧

MySQLで希望通りに並べ替えるsql

d_neko

総合スコア108

MySQL

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

1クリップ

投稿2019/08/12 03:47

編集2019/08/12 04:21

mysqlのこの「hoge」テーブルを

id where who
1 osaka ccc
2 tokyo fff
3 osaka bbb
4 tokyo eee
5 osaka aaa
6 tokyo ddd

id doko who
1 tokyo ccc
2 osaka fff
3 tokyo bbb
4 osaka eee
5 tokyo aaa
6 osaka ddd

このように並べたいと思っています。

id where who
1 osaka ccc
3 osaka bbb
5 osaka aaa
2 tokyo fff
4 tokyo eee
6 tokyo ddd

id doko who
1 tokyo ccc
3 tokyo bbb
5 tokyo aaa
2 osaka fff
4 osaka eee
6 osaka ddd

現在は,dokoに最初に出てきた順番に並べるために

where
tokyo
osaka

を抽出して、再度検索しています。

これを1回のsqlで、できないでしょうか。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

doko別のidの最小値を、並び順の項目とすれば良さそうです。

SQL

1select hoge.* 2from hoge inner join ( 3 select doko, min(id) as sort_id 4 from hoge 5 group by doko 6 ) as sort 7 on hoge.doko=sort.doko 8order by sort_id, id

投稿2019/08/12 04:59

編集2019/08/12 05:39
sazi

総合スコア25173

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/08/12 05:16

おす! sazi はSQL、超つえぇ奴だったよな。おめぇのSQLでわかんねぇ事があるからちょっと教えてくれ。 それでどうやって、複数あるdokoの並び順を指定したらいいんだ? あと、初心者相手にタイポはやめとけ。
退会済みユーザー

退会済みユーザー

2019/08/12 05:19

>現在は,dokoに最初に出てきた順番に並べるために これ固定でいいのか。なら問題ねぇのか。 わりぃわりぃ。
sazi

2019/08/12 05:41

@goku59 さん タイポ指摘、ありがとうございました。
d_neko

2019/08/12 08:12

別のsqlの質問でもお世話になりました。あの時、本当に聞きたかったのはこの質問です。さて、あの回答を見て思ったのが、「サブクエリを使えば1回でできないかな」です。しかし、「MySQLの場合はサブクエリーが遅い」のですか?これは困ります。これは、その問題がないのでしょうか?
退会済みユーザー

退会済みユーザー

2019/08/12 08:18

>しかし、「MySQLの場合はサブクエリーが遅い」のですか?これは困ります。これは、その問題がないのでしょうか? それはおめぇ、レコードが何件あるかによるな。あと、MySQLのバージョンにもよる。 古いMySQLは常に1つのindexしか使用しなかったから遅ぇが、 新しいMySQLはそうじゃねぇ。 どういうSQLを書いたら速くなるかは取りたい内容によって変化するので、 「こうやれば正解」って1つだけの解はねぇ。 だから、DB専門のエンジニアが居る。 ただまぁ、数万行程度の話なら考えるだけ無駄で一瞬で結果が返ってくる。 もっとおめぇの求めている条件を出せ。 そうしねぇと、回答者がおめぇのわけのわかんねぇ質問に振り回されて、 だんだん嫌気がさして去っていくだけだから、おめぇのためにならねぇんじゃねぇかと、 おら、思うぞ。
d_neko

2019/08/12 08:42

ありがとうございます。 >もっとおめぇの求めている条件を出せ。 昔はそうではなかったのですが、 最近、質問すると、質問の内容が、 回答者の都合のいいように変えられたりすることがあります。 回答者の質問に対する質問も、 「それって本当に必要?」ってのもよくあります。 私には、ポイント稼ぎを楽しんでいるようにしか見えないことが多々あります。 今回のように、質問じたい否定されることもあります。 例:そもそもなぜそんな取り出し順にしなきゃいけないのですか? だから、ここでの質問も、まともな回答されたら 「ラッキー」ぐらいにしか考えていませんでした。 そのため、条件を限りなく削除しています。
退会済みユーザー

退会済みユーザー

2019/08/12 08:57 編集

>今回のように、質問じたい否定されることもあります。 >例:そもそもなぜそんな取り出し順にしなきゃいけないのですか? ははは、しぶやんの事か。あいつ、頭固ぇからな。 悪気はねぇみてぇなんだが、融通が効かねぇ。 他の奴もそうなんだが、基本的に言われたことしか出来ねぇ。それをするのが仕事だと思ってる。 プログラマなんて、大体そんなもんだ。ロボばっかだからな。 おらは、考えすぎる。 だから、おめぇのタイトルを見た時点で『多分こういう事がしてぇんだろうな』と思って回答した。 その後で sazi の回答見て『へ? そんだけの事でよかったのか?』って思ったくれぇだ。 結局、前提条件で回答はマイナス100にもプラス10000にもなるんだ。 だからな、ロボ相手なんだって理解して、 どういう物がほしいのかをちゃんと説明するのは、 おめぇの責任じゃなくて、おめぇが一番得をする道だと、おら、思うぞ。
guest

0

おす!

ちょっと、おめぇの希望とは違うかもしんねぇけんどもよぅ、
こんなやり方じゃダメか?

SQL

1SELECT T.* 2FROM 3( 4 SELECT 5 *, 6 CASE 7 WHEN doko = 'osaka' THEN 1 8 WHEN doko = 'tokyo' THEN 2 9 WHEN doko = 'aichi' THEN 3 10 ELSE 999 11 END AS sort_idx 12 FROM test.hoge 13) AS T 14ORDER BY T.sort_idx ASC;

プログラムで動的にSQL生成していいならUNIONすりゃいいだけなんだが、
SQLだけでやろうと思ったら、
とりあえずおらが思いつくのはこういうやり方だな。

他のやつ用にCREATE TABLEとINSERT置いとくぞ。

SQL

1CREATE TABLE `test`.`hoge` ( 2 `id` bigint(20) NOT NULL AUTO_INCREMENT, 3 `doko` varchar(128) DEFAULT NULL COMMENT '場所', 4 `who` varchar(128) DEFAULT NULL COMMENT '誰', 5 PRIMARY KEY (`id`) 6) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='テストテーブル'; 7 8INSERT INTO `test`.`hoge` 9( 10 `doko`, `who` 11) 12VALUES 13('tokyo', 'ccc'), 14('osaka', 'fff'), 15('tokyo', 'bbb'), 16('osaka', 'eee'), 17('tokyo', 'aaa'), 18('osaka', 'ddd'), 19('aichi', 'zzz');

投稿2019/08/12 05:12

編集2019/08/12 05:25
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hihijiji

2019/08/12 07:10

goku59さの回答が一番近い気がします。 あと ORDER BY 句に T.id を加えてくだされ もっと細かいこと言うとtokyoが1かと…
退会済みユーザー

退会済みユーザー

2019/08/12 07:22

>もっと細かいこと言うとtokyoが1かと… そうじゃねぇ。 希望通りに並ぶことをひと目で分かるように、あえてosakaを最初にしてんだ。 でも、質問者が望んでるのは登録されたログでの初出順みてぇだから、sazi のが一番近かったのか?って、おら、思ってるんだけんどもな。 T.id ASC についてはな、『そこはおめぇでも分かるはずだから、おめぇがやれ』って意味で省いた。 全部おらがやっちまったら、質問者の勉強にならねぇからな。
d_neko

2019/08/12 07:56

ありがとうございます。sqlがよくわかっていませが、これだと、新しいデータが増えるたびに、WHENを増やさなければいけませんか?「プログラムで動的にSQL生成していいならUNION」ってやつだと、簡単に出来るのでしょうか。
退会済みユーザー

退会済みユーザー

2019/08/12 07:59

おす! >「プログラムで動的にSQL生成していいならUNION」ってやつだと、簡単に出来るのでしょうか。 おお、ものすげぇ簡単だぞ。SQLを動的に生成する事自体はな。 だけんども、そのプログラムを覚えるのがてぇへんだ。 おめぇはどうしてぇ? それを聞いたら、おらや他のやつが、 きっといいアドバイスできんぞ。
guest

0

最初に出てきたっていうのは id 順に並べたときのことでしょうか?

sql

1SELECT A.* FROM hoge A 2 ORDER BY 3 (SELECT MIN(b.id) FROM hoge B WHERE B.doko = A.doko),id

投稿2019/08/12 05:06

編集2019/08/12 05:57
KOZ6.0

総合スコア2626

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2019/08/12 05:09

order by にサブクエリー使えます?
KOZ6.0

2019/08/12 05:19

最新の 8.0.17 だと使えましたよ。 ひょっとして古いとつかえなかったりします?
sazi

2019/08/12 05:46 編集

>ひょっとして古いとつかえなかったりします? どうなんでしょう。 リファレンスではサブクエリーが使えるような記述には見えないので使ったことは無いです。 MySQLはselectのエイリアスでもorder by の項目として使用できるので、サブクエリー使用するなら、 select で使用する場合が多いとは思いますけど。
KOZ6.0

2019/08/12 05:49

まぁ、d_neko さんの環境で動けばOKかと。 動かなかったらバージョンを確認して報告していただけるとありがたいです。>d_neko さん
sazi

2019/08/12 05:55 編集

質問のサンプル見ると、order by にidが必要な気がします。 サブクエリー版も考えたんですけど、MySQLの場合はサブクエリーが遅いというのもあるので、私はインラインビューでの回答にしました。 d_nekoさんに、この辺の比較も報告してもらえると尚良いと思います。
KOZ6.0

2019/08/12 05:59 編集

sazi さんご指摘ありがとうございました。 id 追加しておきました。
d_neko

2019/08/12 08:26

ありがとうございます。sqlはよくわかっていませんが、サブクエリを使えばいいんじゃないかなと思っていました。でも、「MySQLの場合はサブクエリーが遅い」ようなので「インラインビュー」ってのが気になっています。実際のデータは、100万件くらいだと思うのですが、そのデータがそろうのは、かなり先になります。今、その違いがテストできないので残念です。
KOZ6.0

2019/08/12 09:32 編集

データについては INSERT INTO hoge(doko, who) SELECT doko,who FROM hoge を実行するとデータの数が x2 になるんで、繰り返せばすぐ増やせるかと。 20 万件くらいでやってみたんですが、sazi さんのクエリが数秒で帰ってくるのに対して私のクエリは 30秒タイムアウトしてしまいました。 ここまで違うんですね。
d_neko

2019/08/12 11:51

報告ありがとうございます。まさか、そんなに違いがあるとは思いませんでした。でも、サブクエリって普通の機能じゃないのですか?それがそんなに時間がかかるなんて・・・
KOZ6.0

2019/08/12 12:09

ざっと調べてみたんですが、すべてのサブクエリが遅いというわけではなく、サブクエリで外側のクエリ項目を参照してると遅いようです。(私のクエリでは WHERE B.doko = A.doko のところ) 「MySQL サブクエリ 遅い」でググってみるといろいろ出てくるので参照してみてください。
KOZ6.0

2019/08/12 12:18

これは私の環境(インストールただけのチューニングなし&ショボPC)での話ですから、ちゃんとしたサーバーだと違う可能性があります。この差が覆るとは思えませんが、d_neko さん自身の手で確認していただければと思います。
guest

0

カラム名に予約語が入っているのはちょっといただけないですね。

sql

1select * from `hoge` ordere by `where` asc

投稿2019/08/12 03:51

編集2019/08/12 03:52
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

d_neko

2019/08/12 04:14

もし、osakaとtokyoが逆の場合、希望通りになりません。whereに最初に出てきた順に並べたいとおもっています。
退会済みユーザー

退会済みユーザー

2019/08/12 04:17 編集

なにいってるの? そもそもなぜそんな取り出し順にしなきゃいけないのですか?
退会済みユーザー

退会済みユーザー

2019/08/12 04:52

おす! >Kosuke_Shibuya >なにいってるの? いや、おめーが何言ってんだ。タイトルよく見てみろ。 >MySQLで「希望通りに」並べ替えるsql だぞ。
退会済みユーザー

退会済みユーザー

2019/08/12 04:54

>そもそもなぜそんな取り出し順にしなきゃいけないのですか? そういう物が求められてっからだろ。システム開発やったことねぇのか? プログラマの都合で仕様決まるんじゃねぇぞ。 仕様を満たすようにプログラムを組むんだ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問