SQLでユニオンを使用して注文する方法は?


201

データが多くの選択からのものであり、それらを一緒に結合するときに注文できますか?といった

Select id,name,age
From Student
Where age < 15
Union
Select id,name,age
From Student
Where Name like "%a%"

このクエリを名前で並べ替える方法を教えてください。

このようにクエリを実行できると言う人もいます。

Select id,name,age
From Student
Where age < 15 or name like "%a%"
Order by name

しかし、この場合、その解決策は無視します。


1
ユニオンクエリに同じ列がある場合は、最後に列名で並べ替えます。
anirban karak

回答:


266

書くだけ

Select id,name,age
From Student
Where age < 15
Union
Select id,name,age
From Student
Where Name like "%a%"
Order by name

順序付けは完全な結果セットに適用されます


45
UNIONの最初の1つだけに並べ替えを適用する場合はどうなりますか?
marifrahman

7
@marifrahman私の回答を見るstackoverflow.com/a/43855496/2340825
BA TabNabber

2
@marifrahmanは古いトピックを掘り下げて申し訳ありませんが、他の人を助けるかもしれません。ORDER BYをUNIONの最初の部分に適用する場合は、このSELECTを括弧で保護します。
Lideln極

82
Select id,name,age
from
(
   Select id,name,age
   From Student
   Where age < 15
  Union
   Select id,name,age
   From Student
   Where Name like "%a%"
) results
order by name

46
bernd_kが指摘したように、定義上、UNIONを構成する個々のSELECTには、ORDER BY句を含めることはできません。許可される唯一のORDER BY句はUNIONの最後にあり、UNION全体に適用されます。これはxxx UNION yyy ORDER BY zzz(xxx UNION yyy) ORDER BY zzz
Nicholas Carey

39

ソートをUNIONの最初のステートメントのみに適用するには、UNION ALLを使用してそれを副選択に入れることができます(Oracleではこれらの両方が必要と思われます)。

Select id,name,age FROM 
(    
 Select id,name,age
 From Student
 Where age < 15
 Order by name
)
UNION ALL
Select id,name,age
From Student
Where Name like "%a%"

または、(Nicholas Careyのコメントに対処する)次のように、上位SELECTが順序付けされ、結果が下位SELECTの上に表示されることを保証できます。

Select id,name,age, 1 as rowOrder
From Student
Where age < 15
UNION
Select id,name,age, 2 as rowOrder
From Student
Where Name like "%a%"
Order by rowOrder, name

4
はい。これにより、副選択の結果が並べ替えられます。そのselect副選択を参照するステートメントの結果は順序付けされません。SQL標準に従って、結果の順序は明示的なorder by句を除いて未定義です。これselectは、例では最初に、副選択によって返された順序で結果を返す可能性がありますが、保証されていません。さらに、それ全体の結果セットの順序を保証するわけはありませんunion(規格の同じルール)。順序に依存している場合は、最終的には噛まれます。
ニコラスキャリー2017年

1
@Nicholas Carey-私が最初にUNIONを使用してテストしたとき、あなたが説明したように予期せぬ動作をしていましたが、(少なくともOracleでは)UNION ALLが一番上のSELECTを一番下に並べる必要があると思います。ただし、正しい順序を保証し、データベースに依存しない代替を提供しました。
BA TabNabber

私のために働いていません。UNION ALLを含むものは、最初の内の順序を維持できませんSELECT
Amit Chigadani

また、2番目のクエリの問題は、重複するレコードを排除しないことです。重複レコードに対して異なる値を持つ可能性がある別の列「rowOrder」を追加したためです。UNION ALLに対するUNIONの目的は失われます。
Amit Chigadani

1
@AmitChigadani重複の排除は元の質問の一部ではありませんでしたが、そのためには、一意性を確保するためにWHERE句を変更できます。例:「%a%」のような名前と年齢> = 15
BA TabNabber

12

他の両方の答えは正しいですが、行き詰まった場所ではエイリアスによる順序付けが必要であり、エイリアスが両方の選択で同じであることを確認する必要があることを認識していないことに注意する価値があると思いました...

select 'foo'
union
select item as `foo`
from myTable
order by `foo`

最初の選択では単一引用符を使用していますが、他の引用符にはバッククォートを使用しています。

これにより、必要な並べ替えを行うことができます。


最初の選択で単一引用符を使用し、他の引用符でバッククォートを使用することで重要なことは何ですか?理想的には一貫している必要があります。
nanosoft、2017年

最初の選択はリテラルです。「NAMES」のようなヘッダーです。2番目の選択は、テーブルへの参照です。したがって、最初の行は「NAMES」と表示され、残りの行はテーブルから選択された実際の名前になります。ポイントは、ヘッダーが選択元の列の名前と同じ文字列である可能性が非常に高いことです。これは、ユニオンで衝突することなく、必要なラベルを使用するためのソリューションです。
Yevgeny Simkin 2017年

2
いくつかの実験の後、ORDER BY句で言及されたエイリアスがSELECT句で言及されなければならないことがわかりました。別の列で並べ替えることはできません。もちろんSELECT a, b, c FROM (<insert union query here>) AS x;、余分な列を返さないようにする場合は、全体をaでラップすることで回避できます。
Wodin 2018年

11

Order Byの後unionに適用されるためorder by、ステートメントの最後に句を追加するだけです。

Select id,name,age
From Student
Where age < 15
Union
Select id,name,age
From Student
Where Name like '%a%'
Order By name

9

Union allを使用している場合に、ソートをUNIONの1つだけに適用する場合:

Select id,name,age
From Student
Where age < 15
Union all
Select id,name,age
From 
(
Select id,name,age
From Student
Where Name like "%a%"
Order by name
)

8

他の回答が述べたように、LAST Unionの後の「Order by」は、ユニオンによって結合された両方のデータセットに適用する必要があります。

2つのデータセットを使用していましたが、異なるテーブルを使用していますが、列は同じです。LAST Unionが機能しなくなった後の「注文方法」。「order by」で使用される列にALIASを使用することでうまくいきました。

Select Name, Address for Employee 
Union
Select Customer_Name, Address from Customer
order by customer_name;   --Won't work

したがって、解決策はエイリアス 'User_Name'を使用することです。

Select Name as User_Name, Address for Employee 
Union
Select Customer_Name as User_Name, Address from Customer
order by User_Name; 

-1

これを使用できます:

Select id,name,age
From Student
Where age < 15
Union ALL
SELECT * FROM (Select id,name,age
From Student
Where Name like "%a%")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.