← Kursa Dön
📄 Text · 25 min

ORDER BY — ASC, DESC, Birden Fazla Sütun

Giriş — Verinin Düzeni

Veritabanı sorgusu yazıp sonuçları alıyorsun — ama sonuçlar rastgele bir sırada geliyor. En pahalı ürünü en üstte görmek istiyorsun, en yeni siparişler önce gelmeli, müşteriler A'dan Z'ye sıralı olmalı... İşte ORDER BY tam olarak bunu yapar.

Veritabanı tablolarında satırların doğal bir sırası yoktur. Verilerin diskten okunma sırası, ekleme sırası veya başka bir içsel sıraya bağlı olabilir ve bu garantili değildir. Eğer belirli bir sırada sonuç istiyorsan, mutlaka ORDER BY kullanmalısın.

🎯 Analoji: Bir kütüphanedeki kitaplar düşün. Raflara atılmış kitaplar arasında bir şey bulmak zor. Ama yazara göre, konuya göre veya yayın yılına göre sıralı olduğunda istediğini anında bulursun. ORDER BY, sorgu sonuçlarını "rafa düzenli koymak" gibidir.


Temel Sözdizimi

SELECT sütunlar
FROM tablo
WHERE koşul          -- opsiyonel
ORDER BY sütun [ASC|DESC];

ASC (Artan) ve DESC (Azalan)

-- Fiyata göre artan sıralama (ucuzdan pahalıya)
SELECT product_name, price 
FROM products 
ORDER BY price ASC;
-- ASC varsayılandır, yazılmasa da artan sıralama yapılır

-- Fiyata göre azalan sıralama (pahalıdan ucuza)
SELECT product_name, price 
FROM products 
ORDER BY price DESC;

ASC (Ascending — Artan):

  • Sayılar: 1, 2, 3, 10, 100

  • Metinler: A, B, C, ... Z (alfabetik)

  • Tarihler: eski → yeni

DESC (Descending — Azalan):

  • Sayılar: 100, 10, 3, 2, 1

  • Metinler: Z, ... C, B, A (ters alfabetik)

  • Tarihler: yeni → eski

-- Sipariş tarihi: en yeniden en eskiye
SELECT order_id, order_date, total_amount 
FROM orders 
ORDER BY order_date DESC;

-- Müşteriler alfabetik sırada
SELECT first_name, last_name 
FROM customers 
ORDER BY first_name ASC;
-- ASC yazmasan da aynı sonucu verir (varsayılan)

Birden Fazla Sütuna Göre Sıralama

İlk sütundaki değerler eşit olduğunda, ikinci sütuna göre sıralama yapılır:

-- Önce şehre göre (A-Z), sonra soyada göre (A-Z)
SELECT first_name, last_name, city 
FROM customers 
ORDER BY city ASC, last_name ASC;

-- Sonuç:
-- Ankara  | Kaya     | ...
-- Ankara  | Koç      | ...
-- Antalya | Şahin    | ...
-- Bursa   | Öztürk   | ...
-- İstanbul| Arslan   | ...
-- İstanbul| Aydın    | ...
-- İstanbul| Çelik    | ...
-- İstanbul| Yılmaz   | ...
-- İzmir   | Demir    | ...
-- İzmir   | Yıldız   | ...

Gördüğün gibi: İstanbul'daki 4 müşteri kendi aralarında soyadına göre sıralandı.

Farklı Yönlerde Sıralama

-- Sipariş durumuna göre artan, tutara göre azalan
SELECT order_id, status, total_amount 
FROM orders 
ORDER BY status ASC, total_amount DESC;

-- Kategoriye göre artan, fiyata göre azalan
SELECT product_name, category_id, price 
FROM products 
ORDER BY category_id ASC, price DESC;
-- Her kategori içinde en pahalı ürün en üstte

Sütun Pozisyonuyla Sıralama

Sütun adı yerine SELECT listesindeki pozisyon numarası kullanabilirsin:

-- 2. sütuna göre sırala (price)
SELECT product_name, price FROM products ORDER BY 2 DESC;

-- Bu, aşağıdakiyle aynıdır:
SELECT product_name, price FROM products ORDER BY price DESC;

⚠️ Dikkat: Pozisyon numarası kullanmak kötü pratiktir çünkü: - SELECT listesinde sütun ekleme/çıkarma yapılırsa sıralama bozulur - Kodu okuyan kişi "2" nin ne olduğunu anlamaz - Bakımı zor Her zaman sütun adını yaz.


İfade ve Hesaplama ile Sıralama

ORDER BY'da hesaplama da yapabilirsin:

-- KDV dahil fiyata göre sırala
SELECT product_name, price, price * 1.20 AS price_with_vat
FROM products
ORDER BY price * 1.20 DESC;

-- Veya alias kullanarak (ORDER BY'da alias çalışır!)
SELECT product_name, price, price * 1.20 AS price_with_vat
FROM products
ORDER BY price_with_vat DESC;

-- String uzunluğuna göre sırala
SELECT product_name, LENGTH(product_name) AS name_length
FROM products
ORDER BY name_length DESC;

💡 İpucu: WHERE'de alias kullanılamaz ama ORDER BY'da kullanılabilir. Çünkü SQL değerlendirme sırasında ORDER BY en son çalışır (SELECT'ten sonra).

Değerlendirme sırası:
1. FROM
2. WHERE    ← alias henüz yok
3. GROUP BY
4. HAVING
5. SELECT   ← alias burada tanımlanır
6. ORDER BY ← alias burada kullanılabilir
7. LIMIT

ORDER BY ve NULL

-- NULL değerler sıralamada nereye düşer?
SELECT first_name, phone 
FROM customers 
ORDER BY phone ASC;
-- MySQL: NULL'lar EN BAŞTA (en küçük muamelesi)

-- NULL'ları sona göndermek istiyorsan:
SELECT first_name, phone 
FROM customers 
ORDER BY phone IS NULL ASC, phone ASC;
-- İlk sıralama: NULL olmayanlar (0) → NULL olanlar (1)
-- İkinci sıralama: NULL olmayanlar kendi aralarında artan

-- Başka bir yöntem:
SELECT first_name, phone 
FROM customers 
ORDER BY COALESCE(phone, 'ZZZZZ') ASC;
-- NULL'lar 'ZZZZZ' yerine geçer → sona düşer

ORDER BY ve Collation (Sıralama Kuralları)

Metin sıralaması, veritabanının collation ayarına bağlıdır:

-- utf8mb4_unicode_ci ile:
-- a, A, b, B, c, C, ç, Ç, ... (case-insensitive, Türkçe sıralama)

-- utf8mb4_turkish_ci ile:
-- a, b, c, ç, d, e, f, g, ğ, h, ı, i, j, k, l, m, n, o, ö, p, r, s, ş, t, u, ü, v, y, z
-- (Türkçe alfabe sırası!)

-- Sıralama collation'ını sorgu bazında değiştirebilirsin:
SELECT product_name FROM products 
ORDER BY product_name COLLATE utf8mb4_turkish_ci ASC;

FIELD() ile Özel Sıralama

Önceden belirlenmiş bir sıraya göre sıralamak istersen:

-- Sipariş durumunu özel sıraya göre sırala
SELECT order_id, status, total_amount
FROM orders
ORDER BY FIELD(status, 'pending', 'processing', 'shipped', 'delivered', 'cancelled');
-- pending → processing → shipped → delivered → cancelled sırasında

-- FIELD() olmadan bu sırayı yapman çok zor olurdu
-- FIELD(val, v1, v2, v3) → val'ın listedeki pozisyonunu döndürür
-- FIELD('shipped', 'pending', 'processing', 'shipped', 'delivered', 'cancelled') → 3

Bu pattern, ENUM sütunlarının iş mantığı sırasına göre sıralanmasında çok kullanılır.


ORDER BY ve Performans

-- Index olan sütuna göre sıralama → HIZLI
SELECT * FROM products ORDER BY product_id ASC;
-- product_id primary key (indexli) → index sırası kullanılır

-- Index olmayan sütuna göre sıralama → YAVAŞ (filesort)
SELECT * FROM products ORDER BY product_name ASC;
-- product_name'de index yoksa → tüm satırlar okunur, bellekte sıralanır

-- EXPLAIN ile kontrol:
EXPLAIN SELECT * FROM products ORDER BY product_name ASC;
-- Extra: "Using filesort" görürsen → index yok, yavaş olabilir

💡 İpucu: Sıklıkla ORDER BY yaptığın sütunlara index oluşturmayı düşün. Özellikle büyük tablolarda (100K+ satır) fark dramatiktir. Index konusunu B10'da detaylıca göreceğiz.


Gerçek Dünya Örneği — E-Ticaret Sıralama Senaryoları

-- 1. En çok satan ürünler (stok azalana göre, en az stok = en çok satılmış)
SELECT product_name, stock_quantity, price
FROM products
WHERE is_active = TRUE
ORDER BY stock_quantity ASC;

-- 2. Son siparişler (en yeni önce)
SELECT o.order_id, c.first_name, c.last_name, o.order_date, o.total_amount, o.status
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
ORDER BY o.order_date DESC;

-- 3. Müşteri listesi: şehre göre, sonra ada göre
SELECT first_name, last_name, city, email
FROM customers
WHERE is_active = TRUE
ORDER BY city ASC, first_name ASC, last_name ASC;

-- 4. Sipariş durumunu iş akışı sırasına göre sırala
SELECT order_id, status, total_amount, order_date
FROM orders
ORDER BY FIELD(status, 'pending', 'processing', 'shipped', 'delivered', 'cancelled'),
         order_date DESC;
-- Önce bekleyen siparişler (acil), içlerinde en yenisi önce

Sıkça Yapılan Hatalar

  1. ORDER BY olmadan sıralama beklemek: SELECT * FROM customers her zaman aynı sırada sonuç döndürmek zorunda değildir. Belirli bir sıra istiyorsan ORDER BY yaz.

  2. Pozisyon numarası kullanmak: ORDER BY 3 yazmak kırılgan ve okunaksızdır. Sütun adı kullan.

  3. Performansı ihmal etmek: Milyonlarca satırda ORDER BY + LIMIT olmadan sorgu yazmak sunucuyu zorlayabilir. LIMIT ile birlikte kullan.

  4. ASC/DESC'i karıştırmak: Birden fazla sütunda sıralama yaparken her sütun için yönü ayrı belirle. Pahalıdan ucuza istiyorsan DESC, A-Z istiyorsan ASC.

  5. NULL sıralama davranışını bilmemek: MySQL'de NULL ASC sıralamada en başta gelir. Bu, "en düşük fiyatlı ürünler" sorgusunda fiyatı NULL olan ürünlerin en üstte çıkmasına neden olur.


Özet

  • ORDER BY sütun ASC artan, ORDER BY sütun DESC azalan sıralama yapar

  • ASC varsayılandır — yazılmazsa artan sıralama uygulanır

  • Birden fazla sütuna göre sıralama: ORDER BY sütun1 ASC, sütun2 DESC

  • ORDER BY'da alias kullanılabilir (WHERE'den farklı olarak)

  • FIELD() fonksiyonu ile özel sıralama tanımlanabilir

  • NULL değerler ASC'de en başta, DESC'de en sonda çıkar

  • ORDER BY olmadan belirli bir sıra garanti değildir

  • Sıralama performansı için index önemlidir