MySQL Bir numaraya göre sırala, Boş değerler son


280

Şu anda açıklamamda çok temel bir OrderBy yapıyorum.

SELECT * FROM tablename WHERE visible=1 ORDER BY position ASC, id DESC

Buradaki sorun, 'position' için NULL girdilerin 0 olarak işlem görmesidir. Bu nedenle NULL olarak konumlandırılmış tüm girdiler 1,2,3,4 olanlardan önce görünür. Örneğin:

NULL, NULL, NULL, 1, 2, 3, 4

Aşağıdaki siparişi elde etmenin bir yolu var mı:

1, 2, 3, 4, NULL, NULL, NULL.

8
User1052645 kullanıcısının yanıtını yeniden düşünmelisiniz. Daha basittir, maksimum değerler hakkında bilgi gerektirmez ve daha hızlı olabilir (bir ifadeyi değerlendirmek bir işlev çağrısından daha hızlı olabilir).
Steve Clay

Yanıtlar:


568

MySQL, null değerlerini son olarak sıralamak için belgesiz bir sözdizimine sahiptir. Sütun adının önüne bir eksi işareti (-) koyun ve ASC'yi DESC olarak değiştirin:

SELECT * FROM tablename WHERE visible=1 ORDER BY -position DESC, id DESC

Temelde position DESCNULL değerlerinin son yerleştirilmesinin tersi, aksi takdirde aynıposition ASC .

İyi bir referans burada http://troels.arvin.dk/db/rdbms#select-order_by


79
Belgelenmemiş, ORDER BY deyiminin kabul ettiği - col_namebir ifade ( 0 - col_name). Tabii ki bu sadece sayısal sütunlar için geçerlidir.
Steve Clay

7
Güzel bir. İçin İşleri dateve timeçok kolonlar! (MySQL 5.5). Sanırım (kontrol etmek için tembelim) tüm sayı benzeri sütunlar için çalışır (zaman damgası, kayan nokta ...).
Martin

6
@koral: Sırayı tersine çeviren basit (ve kullanışlı) bir matematik ifadesidir, dilin kendisi önemli ölçüde değişmedikçe kaldırılmaz.
Bell

11
Yorumların önerdiği gibi, sayısal, tarih ve saat sütunları için çalışıyor mu? Peki ya varchar? Varchar için de uygulanabilir mi? Varchar alanlarına uygulamayı denedim, ancak sipariş ASC veya DESC kullanmaktan farklı görünüyor.
Sumit Desai

9
Bu, sütuna göre siparişte olası bir dizinin kullanılmasını engellemez mi?
Tarsis

306

Bunu çoğunlukla iyi bir çözüm olarak buldum:

SELECT * FROM table ORDER BY ISNULL(field), field ASC;

6
Eserleri iş sırasına göre yeniden tanımlamadan: SELECT * FROM table ORDER BY ISNULL(field) ASC;(MySQL 5.5)
Marçal Juan

5
Bu daha iyi bir çözüm.
Rok Kralj

4
Kabul edilen çözüm postgresql 9.3'te TIMESTAMP ile çalışmaz. Bu çözüm ...
Kalu

2
Rahatsız edici bir şekilde, siparişe isnull (field) ekini (limit kullanırken) eklediğinizde MySQL alanda bir dizin kullanmaz.
Barry Kelly

3
@kalu: PostgreSQL'de NULL değerler son sırada artan sırada (ilk sırada azalan sırada) sıralanır. Ve yerine standart SQL yan tümcesiniNULLS LASTNULLS FIRST kullanın | buradaki geçici çözümler yerine ters çevirmek.
Erwin Brandstetter

23

Gibi bir şey

SELECT * FROM tablename where visible=1 ORDER BY COALESCE(position, 999999999) ASC, id DESC

999999999 değerini alan için maksimum değerle değiştirin


3
Bu çözüm kırılgandır ve aralıklı hatalara neden olabilir
Dmitry Bogdanovich

20

NULL SON

SELECT * FROM table_name ORDER BY id IS NULL, id ASC

4

İlk olarak (0 veya -1 gibi) veya son olarak (büyük bir sayı veya bir harf) sıralamak için NULL örneklerini farklı bir değerle değiştirebilirsiniz ...

SELECT field1, IF(field2 IS NULL, 9999, field2) as ordered_field2
  FROM tablename
 WHERE visible = 1
 ORDER BY ordered_field2 ASC, id DESC

ORDER BY içinde başvurulan dizin SELECT deyimindeki değerlerin değiştirilmesinden etkilenmeyeceği ve bu nedenle sıralamayı düzeltmeyeceği için bu sorunu çözmez. Ayrıca, IF işlevini kullanımınıza işlevsel olarak eşdeğer olan COALESCE işlevine de göz atın.
tanımlar

IF deyimini düzgün bir şekilde diğer adınıza takarsanız, satırlar beklediğiniz gibi sıralanır. Örneğimi düzelttim.
Langdon

4

Bu sorguyu kullanmayı deneyin:

SELECT * FROM tablename
WHERE visible=1 
ORDER BY 
CASE WHEN position IS NULL THEN 1 ELSE 0 END ASC,id DESC

Davaya gerek yok. İfade NULL olduğunda IS NULL, 1 değerini döndürür. Yankılanmanın cevabına bakınız.
contactmatt

3

Sen olabilir birleşerek da boş değerlere ORDER BYaçıklamada:

select * from tablename
where <conditions>
order by
    coalesce(position, 0) ASC, 
    id DESC

NULL'ların altta sıralanmasını istiyorsanız, deneyin coalesce(position, 100000). (İkinci sayıyı db'deki diğerlerinden daha büyük yapın position.)


3
SELECT * FROM tablename WHERE visible=1 ORDER BY CASE WHEN `position` = 0 THEN 'a' END , position ASC

6
OP bunu neden denemeli ? İyi cevaplar her zaman ne yapıldığını ve neden bu şekilde yapıldığını açıklar, sadece OP için değil, SO'ya gelecek ziyaretçiler için de bu soruyu bulabilir ve cevabınızı okuyabilir.
RiggsFolly

2

Bir DATEsütun için şunları kullanabilirsiniz:


Son NULLS:

ORDER BY IFNULL(`myDate`, '9999-12-31') ASC

Son boşluklar:

ORDER BY IF(`myDate` = '', '9999-12-31', `myDate`) ASC

1

Aşağıdaki sonucu elde etmek için:

1, 2, 3, 4, NULL, NULL, NULL.

Sözdizimi KULLANIN, -(minus sign)alan adının önüne yerleştirin ve ters order_type kullanın (Gibi: ASC siparişine göre sipariş istiyorsanız DESC kullanın veya DESC siparişini istiyorsanız ASC kullanın)

SELECT * FROM tablename WHERE visible=1 ORDER BY -position DESC


1

Bu iyi çalışıyor:

SELECT * FROM tablename ORDER BY position = 0, position ASC;

position
1 
2
3
0
0

-8

NULLS LAST tarafından neden sipariş vermiyorsunuz?

SELECT * 
FROM tablename
WHERE visible = 1 
ORDER BY position ASC NULLS LAST, id DESC 

NULLS LAST- MySQL'in hangi sürümü tanıtıldı?
crmpicco

2
@Panique, (MS) SQL Server mı demek istediniz?
d -_- b

1
bu cevap MySQL
PeppyHeppy
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.