Belirli kimlik değerlerine göre Mysql sıralaması


96

Önceden tanımlanmış sütun değerleri kümesini (ID) kullanarak mysql'de sıralama yapmak mümkün mü: (ID = 1,5,4,3) gibi, böylece 1, 5, 4, 3 kayıtlarını alabileyim sipariş dışı?

GÜNCELLEME: mysql ;-) kötüye kullanma hakkında buna neden ihtiyacım olduğunu açıklamalıyım ...

Kayıtlarımın 5 dakikada bir rastgele sıralanmasını istiyorum. Farklı, rastgele sıralama düzeni koymak için güncelleme tablosunu yapmak için bir cron görevim var. Sadece bir problem var! SAYFALAMA. Sayfama gelen bir ziyaretçim olacak ve ona ilk 20 sonucu vereceğim. 6 dakika bekleyecek ve 2. sayfaya gidecek ve sıralama düzeni zaten değiştiği için yanlış sonuçlar alacaktır.

Bu yüzden siteme gelirse tüm kimlikleri bir oturuma koyduğumu ve 2. sayfadayken sıralama değişmiş olsa bile doğru kayıtları alacağını düşündüm.

Bunu yapmanın daha iyi başka bir yolu var mı?


Mysql'in belirli bir sırayla sipariş veremeyeceği bir yol olup olmadığını mı soruyorsunuz?
stefgosselin

1
Veri modeli bozuldu ya / tamamlanmamış (gibi geliyor nerede bu düzen geliyor?) Ya da alternatif MySQL olmana gerek yok.
derobert

Yanıtlar:


204

ORDER BY ve FIELD işlevini kullanabilirsiniz. Bkz. Http://lists.mysql.com/mysql/209784

SELECT * FROM table ORDER BY FIELD(ID,1,5,4,3)

Belgelere göre "str1, str2, str3, ... listesindeki dizinin dizinini (konumunu) döndürür. Eğer str bulunamazsa 0 döndürür" olan Field () işlevini kullanır . Yani aslında sonuç kümesini, verilen kümedeki alan değerinin indeksi olan bu işlevin dönüş değerine göre sıralarsınız.


Bunu kullanmadan da çalıştırmayı başaramıyorum: WHERE ID IN (1,5,4,3)
TV-C-15

1
Bunu Yok değerleri ile nasıl kullanırsınız?
Nono Londra

30

Bunun için kullanabilmeniz gerekir CASE:

ORDER BY CASE id
  WHEN 1 THEN 1
  WHEN 5 THEN 2
  WHEN 4 THEN 3
  WHEN 3 THEN 4
  ELSE 5
END

18

ORDER BY ile ilgili mysql için resmi belgelerde , birisi FIELDbu konu için kullanabileceğiniz şu şekilde yayınladı :

SELECT * FROM table ORDER BY FIELD(id,1,5,4,3)

Bu, teoride çalışması gereken test edilmemiş koddur.


7
SELECT * FROM table ORDER BY id='8' DESC, id='5' DESC, id='4' DESC, id='3' DESC

Örneğin 10 kaydım varsa, bu şekilde ID 1, 5, 4 ve 3 ilk olarak görünecek, diğer kayıtlar daha sonra görünecektir.

Normal sergi 1 2 3 4 5 6 7 8 9 10

Bu şekilde

8 5 4 3 1 2 6 7 9 10


Tamam Tavsiye için teşekkürler
Bruno Mangini Alves

6

Bunu çözmenin başka bir yolu var. Ayrı bir tablo ekleyin, şuna benzer:

CREATE TABLE `new_order` (
  `my_order` BIGINT(20) UNSIGNED NOT NULL,
  `my_number` BIGINT(20) NOT NULL,
  PRIMARY KEY (`my_order`),
  UNIQUE KEY `my_number` (`my_number`)
) ENGINE=INNODB;

Bu tablo artık kendi sipariş mekanizmanızı tanımlamak için kullanılacaktır.

Değerlerinizi oraya ekleyin:

my_order | my_number
---------+----------
       1 |         1
       2 |         5
       3 |         4
       4 |         3

... ve sonra bu yeni tabloya katılırken SQL ifadenizi değiştirin.

SELECT *
FROM your_table AS T1
INNER JOIN new_order AS T2 on T1.id = T2.my_number
WHERE ....whatever...
ORDER BY T2.my_order; 

Bu çözüm diğer çözümlerden biraz daha karmaşıktır, ancak bunu kullanarak SELECT, sipariş kriterleriniz her değiştiğinde ifadenizi değiştirmeniz gerekmez - sadece sipariş tablosundaki verileri değiştirin.


1

Sonuçta ilk olarak tek bir kimlik sipariş etmeniz gerekirse, kimliği kullanın.

select id,name 
from products
order by case when id=5 then -1 else id end

Birden çok kimlikle başlamanız gerekiyorsa, bir INifadede kullanacağınıza benzer bir koleksiyon belirtin .

select id,name 
from products
order by case when id in (30,20,10) then -1 else id end,id

Biraz daha açıklama ekleyin
Mathews Sunny

sırayı yalnızca bir kimlik için kullanmak istiyorsanız, 1. sorguyu kullanın ve birden fazla kimlik istiyorsanız 2. sorguyu kullanın
Rajesh Kharatmol

0
SELECT * FROM TABLE ORDER BY (columnname,1,2) ASC OR DESC

2
Bunu biraz daha açıklayabilir misin? Bu, kabul edilen cevaba benziyor, ancak bunun ASC OR DESCdoğru sözdizimi olduğunu düşünmüyorum
Nico Haase

@NicoHaase ASC ve DESC arasındaki fark, eğer asc kullanırsanız, alan işlevinde kullandığınız kimlikler sona erecek ve DESC kullanırsanız, alan işlevindeki kimlikler önce gelecektir
Hisham shahid

Eğer gereksinimi için sorgu tek accroding biriyle ya ASC veya DESC kullanabilirsiniz @NicoHaase
Hisham Şahid

Yani ikisini birden bir sorguda kullanamazsınız. Nico, cevabınızı sözdizimsel olarak doğru yaptığınızı önermişti. ASD ve
DESC'in

0

Sonuçta son olarak tek bir kimlik sipariş etmek istiyorsanız, vakaya göre sıralamayı kullanın. (Örn: en sondaki "diğer" seçeneğini istiyorsunuz ve tüm şehir listeleri alfabetik sırayla gösterilir.)

select id,city 
from city
order by case 
when id = 2 then city else -1 
end, city ASC

Örneğin 5 şehrim olsaydı, açılır menüde en son "diğer" seçeneği ile şehri alfabetik sırayla göstermek istersem bu sorguyu kullanabiliriz. Örneğe bakın, ikinci id'de (id: 2) tablomda diğer gösteriliyor, bu yüzden yukarıdaki sorguda "when id = 2" kullanıyorum.

DB tablosunda kayıt:

Bangalore - id:1
Other     - id:2
Mumbai    - id:3
Pune      - id:4
Ambala    - id:5

çıktım:

Ambala  
Bangalore  
Mumbai  
Pune
Other

2
Kodunuza bir açıklama eklemeye çalışın, cevabınızı daha net ve anlaşılır hale getirecektir. Lütfen stackoverflow.com/help/how-to-answer
32cupo

Sadece bir id için sıralama kullanmak istiyorsanız (Örn: sonda "diğer" seçeneğini istiyorsanız ve tüm şehir listesi alfabetik sırayla gösterilir.), böylece bu sorguyu kullanabilirsiniz. benim için çalışıyor.
Preeti
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.