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

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

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

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

Q&A

解決済

2回答

11168閲覧

SQL:ORDER BYで並び替えたSELECT文をUNION ALLで結合した場合に順番が変わってしまう

yowayowanitohei

総合スコア31

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

0グッド

0クリップ

投稿2021/05/13 07:36

編集2021/05/13 08:22

商品名と日付で複数入力可能な検索機能を作成しており、
PHPにて以下のSQLを自動生成するようにしています。

入力 > りんご,2020-04-16 > みかん,2020-05-02 > レモン,2020-03-12

SQL

1SELECT p.* 2FROM ( 3 SELECT * 4 FROM( 5 SELECT * FROM product 6 WHERE product = 'りんご' AND sold_date <= '2020-04-01' 7 ORDER BY product , sold_date DESC 8 limit 1 9 ) 10 11UNION ALL 12 13SELECT p.* categories.* 14FROM ( 15 SELECT * 16 FROM( 17 SELECT * FROM product 18 WHERE product = 'みかん' AND sold_date <= '2020-05-01' 19 ORDER BY product , sold_date DESC 20 limit 1 21) 22 23UNION ALL 24252627AS p

入力された商品名かつ指定された日付より古い最新のものを1件取得するSQLで、
入力の件数に応じてSELECT文をUNION ALLで接続しています。

結果としては欲しいものが返ってくるのですが、
日付順で勝手にソートされてしまっており、
入力された順番に取ってこれるように修正したいと考えております。

現在の結果 > みかん,2020-05-01,売上,カテゴリー,・・・ > りんご,2020-04-11,売上,カテゴリー,・・・ > レモン,2020-03-12,売上,カテゴリー,・・・ 求める結果 > りんご,2020-04-11,売上,カテゴリー,・・・ > みかん,2020-05-01,売上,カテゴリー,・・・ > レモン,2020-03-12,売上,カテゴリー,・・・

UNION ALLだと順番は変わらないという内容が多いのですが、
UNION前にそれぞれでORDER BYを使用していた場合は順番が変動してしまうのでしょうか。
問題点などご指摘をお願いしたいです。

すみませんが、どうぞよろしくお願い致します。- リスト

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

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

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

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

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

sazi

2021/05/13 07:57 編集

別質問の性能改善に関係していると思うんですが、見たところ、Window関数を使用する代わりにunionにしているようですね。 インデックスのチューニングは行ったのでしょうか?
yowayowanitohei

2021/05/13 07:58

sazi様 ご回答ありがとうございます。 UNIONにすると速度の問題がかなり改善しました。。。 これで正しいデータが取れるならこのままやってしまいたいなと考えています。 (以前のご回答アンサー付けておらず申し訳ないです)
sazi

2021/05/13 08:03

インデックスは追加してその上でSQLを変更しているのですね。 あの実行計画から言える事では、or 条件をunion している事での改善ではなく、 (Window関数を使用する代わりの)SQL構造変更による改善でしょうから、誤解なきよう。
sazi

2021/05/13 08:08

インデックスは追加しておらず、unionで早くなったというなら、それはたまたま、limit 1のデータが早くに見つかっただけで、データの後方にあるような場合は、遅くなるはずですから、性能が安定しない事になりますよ。
sazi

2021/05/13 08:24 編集

(質問が変更されたので削除)
yowayowanitohei

2021/05/13 08:31

sazi様 言葉足らずですみません index追加後に同じ処理だと変わらず原因を探っていました。 その結果or・or・or・で取得よりもunion allの方がかなりスピードが出ていたためこの修正になった次第です。 また、ご指摘ありがとうございます。 sold_date <= '2020-04-01' 正しいものは上記でした。本文修正させていただきました。
sazi

2021/05/13 08:49

> union allの方がかなりスピードが出ていたため 対象データをピンポイントに絞る事で高速になったという事ですね。 実行計画のその後は、別質問に経過報告して貰えれば、アドバイス出来る事はあるかもしれません。
guest

回答2

0

PostgreSQL のマニュアルでも、

UNIONは、query2の結果をquery1の結果に付加します(しかし、この順序で実際に行が返される保証はありません)

とあるので、結合した結果の並び順は(それぞれで order by していたとしても)保証されない、と見るべきでしょう。確実にするならば m.ts10806 さんのいうように、union した結果に対してさらに order by することになるでしょう。

投稿2021/05/13 07:55

tacsheaven

総合スコア13703

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

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

yowayowanitohei

2021/05/13 08:04 編集

tacsheaven様 ご回答ありがとうございます。 マニュアル確認不足でした。。。 日付ランダムでもう少し多めの検索を行ってみたのですが、 どうやら日付でソートされているわけでもなく、取得結果の順番は よくわからないものでした・・・ 「サブクエリでorder by」にいまいちよくイメージができておらず、 そのように修正した場合でも入力順に表示させるには入力自体を日付順で並べ替える必要があり 日付順がランダムな検索を行った場合は表示がおかしくなってしまう ということなのでしょうか。 重ねての質問で申し訳ございません。
guest

0

ベストアンサー

結局はレコード結果を積み重ねてるに過ぎませんので、内部的にソートされたものはそのまま下に下に重なるだけだと思います。
全体のレコードからソートを担保したいのでたらunionした塊を1つの大きなサブクエリにして、そいつに対してorder byするのが確実です。

投稿2021/05/13 07:40

m.ts10806

総合スコア80861

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

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

yowayowanitohei

2021/05/13 08:06

m.ts10806 様 ご回答ありがとうございます。 日付ランダムでもう少し多めの検索を行ってみたのですが、 どうやら日付でソートされているわけでもなさそうでした・・・ 「サブクエリでorder by」にいまいちよくイメージができておらず、 そのように修正した場合でも入力順に表示させるには入力自体を日付順で並べ替える必要があり 日付順がランダムな検索を行った場合は表示がおかしくなってしまう ということなのでしょうか。 重ねての質問で申し訳ございません。
m.ts10806

2021/05/13 08:13

最上部に被せるだけです。 select * from ( 今のSQL ) order by 〜
yowayowanitohei

2021/05/13 08:33

できました! ダミーで番号を振って、それに対してorder by でソートすることによって 検索した順番を正しく表示させることができました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問