Mysqlクエリでunionを使用したorder byを使用します。サイトでの検索の距離に基づいたテーブルから、さまざまな基準に基づいてさまざまな種類のレコードを取得しています。最初の選択クエリは、正確な場所検索に関連するデータを返します。 2番目の選択クエリは、検索された場所から5 km以内の距離に関連するデータを返します。 3番目の選択クエリは、検索された場所から5〜15 km以内の距離に関連するデータを返します。
次に、ユニオンを使用してすべての結果をマージし、ページングでページに表示します。 「正確な検索結果」、「5 km以内の結果」などの適切な見出しの下
ここで、idまたはadd_dateに基づいて結果を並べ替えます。しかし、クエリの最後にorder by句を追加すると(query1 union query 2 union query 3 order by add_date)すべての結果をソートします。しかし、私が欲しいのは、各見出しの下にソートすることです。
これを行うには、各選択にrankという名前の疑似列を追加します。これは、他の基準で並べ替える前に、最初に並べ替えることができます。
select *
from (
select 1 as Rank, id, add_date from Table
union all
select 2 as Rank, id, add_date from Table where distance < 5
union all
select 3 as Rank, id, add_date from Table where distance between 5 and 15
) a
order by rank, id, add_date desc
これを行うには、サブクエリを使用できます。
select * from (select values1 from table1 order by orderby1) as a
union all
select * from (select values2 from table2 order by orderby2) as b
(select add_date,col2 from table_name)
union
(select add_date,col2 from table_name)
union
(select add_date,col2 from table_name)
order by add_date
忘れないでください、union allは、(unionとは対照的に)ソートまたはマージせずにレコードセットにレコードを追加する方法です。
たとえば、次のとおりです。
select * from (
select col1, col2
from table a
<....>
order by col3
limit by 200
) a
union all
select * from (
select cola, colb
from table b
<....>
order by colb
limit by 300
) b
これにより、個々のクエリがより明確になり、各クエリのさまざまなパラメータで並べ替えることができます。ただし、選択した回答の方法を使用すると、並べ替えを概念化するため、複雑さとデータの関連性によっては明確になる場合があります。また、クエリ列に人為的な列を返すことができるため、並べ替えや整理が可能なコンテキストが得られます。
ただし、この方法には、余分な変数を導入せずに、高速で、ソートを含む各クエリを簡単に分離できるという利点があります。制限を追加する機能は、単なる追加のボーナスです。
そしてもちろん、ユニオンをすべてユニオンに変えて、クエリ全体のソートを追加してください。または、人工IDを追加します。この場合、この方法では各クエリの異なるパラメーターで簡単に並べ替えることができますが、それ以外は受け入れられた回答と同じです。
ユニオンクエリに含めることができるマスターORDER BY
句は、IIRCです。これを取得するには、大きいUNION
クエリを構成する各クエリで、UNION
のORDER BY
でソートする1つのフィールドになるフィールドを追加します。
たとえば、次のようなものがあります
SELECT field1, field2, '1' AS union_sort
UNION SELECT field1, field2, '2' AS union_sort
UNION SELECT field1, field2, '3' AS union_sort
ORDER BY union_sort
そのunion_sort
フィールドには、並べ替えに使用できるものなら何でも指定できます。この例では、最初のテーブルの結果を最初に、2番目のテーブルの結果を2番目などに配置するだけです。
私はこれを結合と結合に取り組んでもらいました。
(SELECT
table1.column1,
table1.column2,
foo1.column4
FROM table1, table2, foo1, table5
WHERE table5.somerecord = table1.column1
ORDER BY table1.column1 ASC, table1.column2 DESC
)
UNION
(SELECT
... Another complex query as above
)
ORDER BY column1 DESC, column2 ASC
試してください:
SELECT result.*
FROM (
[QUERY 1]
UNION
[QUERY 2]
) result
ORDER BY result.id
[クエリ1]と[クエリ2]は、マージする2つのクエリです。
これは、結果セット全体をソートしているため、ユニオンのすべての部分を個別にソートするか、ORDER BY(何かつまりサブクエリ距離)THEN(何かつまり行ID)句を使用できるためです
私は次のように結合する前に各クエリに順序を追加しようとしました
(select * from table where distance=0 order by add_date)
union
(select * from table where distance>0 and distance<=5 order by add_date)
しかし、うまくいかないようでした。実際には、各選択からの行内の順序付けは行いませんでした。
私はあなたが外側で順序を維持し、where句の列をorder byに追加する必要があると思う
(select * from table where distance=0)
union
(select * from table where distance>0 and distance<=5)
order by distance, add_date
範囲ごとにグループ化したいので、これは少し難しいかもしれませんが、実行できるはずです。
UNION
とともに使用されるサブクエリ内でORDER BY
句を使用すると、mysqlはORDER BY
句を最適化します。
これは、デフォルトでUNION
が順序付けられていないリストを返すため、ORDER BY
は何もしないためです。
最適化は ドキュメントで に言及されており、次のように書かれています:
ORDER BYまたはLIMITを個々のSELECTに適用するには、SELECTを囲む括弧内に句を配置します。
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION (SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
ただし、個々のSELECTステートメントにORDER BYを使用しても、デフォルトではUNIONによって順序付けられていない行のセットが生成されるため、最終結果に行が表示される順序については何も意味しません。したがって、このコンテキストでのORDER BYの使用は通常、LIMITと組み合わせて使用されるため、SELECTで取得する選択された行のサブセットを決定するために使用されます。最終的なUNION結果。 SELECTでLIMITを指定せずにORDER BYが表示される場合、とにかく効果がないため最適化されます。
この最後の文は、効果があるはずなので、少し誤解を招く可能性があります。この最適化は、サブクエリ内で注文する必要がある場合に問題を引き起こします。
MySQLがこの最適化を行わないようにするには、次のようにLIMIT句を追加できます。
(SELECT 1 AS rank, id, add_date FROM my_table WHERE distance < 5 ORDER BY add_date LIMIT 9999999999)
UNION ALL
(SELECT 2 AS rank, id, add_date FROM my_table WHERE distance BETWEEN 5 AND 15 ORDER BY rank LIMIT 9999999999)
UNION ALL
(SELECT 3 AS rank, id, add_date from my_table WHERE distance BETWEEN 5 and 15 ORDER BY id LIMIT 9999999999)
LIMIT
が高いということは、ページネーションなどを実行する場合、クエリ全体にOFFSET
を追加できることを意味します。
これにより、ユニオンごとに異なる列をORDER BY
できるという追加の利点も得られます。