SQL'de sendika ile nasıl sipariş verilir?


202

Veriler birçok seçenekten geldiğinde sipariş vermek ve birleştirmek mümkün müdür? Gibi

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

Bu sorguyu ada göre nasıl sipariş edebilirim?

Bazıları bunun gibi sorgulayabileceğini söyledi.

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

Ama bu durumda bu çözümü görmezden geliyorum.


1
Birlik sorgusunda aynı sütuna sahipseniz, sonunda sütun adınıza göre sipariş verin.
anirban karak

Yanıtlar:


268

Sadece yaz

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

tarafından siparişin tamamı sonuç kümesine uygulanır


46
Sıralamanın yalnızca BİRLİĞİN ilk zirvesine uygulanmasını istersem ne olur?
marifrahman

7
@marifrahman cevabımı gör stackoverflow.com/a/43855496/2340825
BA TabNabber

2
@ marifrahman eski bir konuyu açtığım için üzgünüm, ama başkalarına yardımcı olabilir. SİPARİŞ BİRLİĞİNİN BİRLİĞİN ilk kısmına uygulanmasını istiyorsanız, bu SELECT öğesini parantez içinde koruyun.
Lideln Kyoku

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'in işaret ettiği gibi, tanım gereği, bir sendika oluşturan bireysel SELECT'lerin ORDER BY yan tümcesi içermesine izin verilmez. İzin verilen tek ORDER BY deyimi BİRLİĞİN sonundadır ve tüm BİRLİĞİ için geçerli olup xxx UNION yyy ORDER BY zzz, eşdeğer hale gelir(xxx UNION yyy) ORDER BY zzz
Nicholas Carey

39

Sıralamanın yalnızca UNION'daki ilk ifadeye uygulanmasını sağlamak için, bunu UNION ALL ile bir alt seçime koyabilirsiniz (bunların her ikisi de Oracle'da gerekli görünmektedir):

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%"

Veya (Nicholas Carey'nin yorumuna değinen), en üstteki SELECT öğesinin sipariş edildiğini ve sonuçların aşağıdaki gibi SELECT'in üst kısmında görüneceğini garanti edebilirsiniz:

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
Evet. Bu, alt seçimin sonuçlarını sıralar. Bu, selectalt seçime gönderme yapan ifadenin sonuçlarını SIRALAMAZ. SQL Standardı uyarınca, sonuçların sırası açık bir order bymaddeyi yasaklayan tanımsızdır . Örneğinizde birincisi select, muhtemelen sonuçlarını alt seçim tarafından döndürülen sırayla döndürür, ancak garanti edilmez. Ayrıca, bütünün sonuç kümesinin sırasını * garanti etmez *union (Standartta aynı kural). Siparişe bağlıysanız, - sonunda - ısırılırsınız.
Nicholas Carey

1
@Nicholas Carey - Bir UNION kullanarak ilk kez test ettiğimde, tarif ettiğiniz gibi beklenmedik bir şekilde davranıyordu, bence UNION ALL (en azından Oracle'da) en üstteki SELECT'i alttan yukarıda sipariş etmek için gerekliydi. Ancak ben doğru sipariş garanti ve veritabanından bağımsız olması gereken bir alternatif sağladım.
BA TabNabber

Benim için çalışmıyor. BİRLİĞİ olan kişi, emri hala birincisi içinde koruyamaz SELECT.
Amit Chigadani

Ve ikinci sorgu ile ilgili sorun, yinelenen kayıtları ortadan kaldırmaz. Çünkü yinelenen kayıtlara göre farklı bir değere sahip olabilecek başka bir 'rowOrder' sütunu eklediniz. BİRLİĞİN BİRLİĞE karşı amacı kaybolur.
Amit Chigadani

1
@AmitChigadani Kopyaların kaldırılması orijinal sorunun bir parçası değildi, ancak bunu yapmak için WHERE yan tümceleri benzersizliği sağlayacak şekilde değiştirilebilir. örneğin: "% a%" gibi bir isim VE yaş> = 15
ad

12

Hem diğer cevaplar doğru, hem de takıldığım yerin takma ad tarafından siparişe ihtiyaç duyacağınızı ve takma adın her iki seçim için de aynı olduğundan emin olduğunuzu fark etmediğini düşündüm.

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

ilk seçimde tek tırnak kullandığımı ancak diğerleri için backticks kullandığımı fark ettim.

Bu size ihtiyacınız olan sıralamayı sağlayacaktır.


ilk seçimde tek tırnak, diğerinde backticks kullanarak yapmak istediğiniz önemli nedir? İdeal olarak tutarlı olmalıdır.
nanosoft

İlk seçim değişmezdir; 'NAMES' gibi bir başlık. İkinci seçim bir tabloya referanstır. Yani ilk satırınız "NAMES" (DOLU) diyecektir ve satırların geri kalanı tablodan seçilen gerçek isimler olacaktır. Mesele şu ki, başlığınız seçtiğiniz sütunun adıyla aynı dize olabilir ve bu, birliğinizde çarpışmadan istediğiniz etiketi kullanmak için bir çözümdür.
Yevgeny Simkin

2
Bazı deneylerden sonra ORDER BY yan tümcesinde belirtilen diğer adın SELECT yan tümcelerinde belirtilmesi gerektiğini görüyorum. Başka bir sütuna göre sıralayamazsınız. Tabii ki SELECT a, b, c FROM (<insert union query here>) AS x;, ekstra sütun döndürmekten gerçekten kaçınmak istiyorsanız , her şeyi bir sarımla sarabilirsiniz.
Wodin

11

Order Bysonra uygulanır union, bu yüzden order byifadelerin sonuna bir cümle ekleyin :

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

9

Eğer Sendika tümünü kullanırsanız, bu türden yalnızca BİRLİĞE uygulanmasını istiyorsanız:

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

Diğer cevapların belirttiği gibi, LAST Union'dan sonra 'Order by', birliğe katılan her iki veri kümesine de uygulanmalıdır.

İki veri kümesi vardı ama farklı tabloları ama aynı sütunları kullanarak. LAST Union hala çalışamadıktan sonra 'Siparişi ver'. 'Sırayla' kullanılan sütun için ALIAS kullanmak hile yaptı.

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

Yani çözüm 'Takma Ad' Kullanıcı_Adı 'kullanmaktır:

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

-1

Bunu kullanabilir:

Select id,name,age
From Student
Where age < 15
Union ALL
SELECT * FROM (Select id,name,age
From Student
Where Name like "%a%")
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.