İçeriğe geç
academia.sh

Ders 04 / 18

Sıralama ve Sınırlama

Sonuç kümesinin sıralanması, çok anahtarlı sıralama, harmanlamanın sıra üzerindeki etkisi, boş değerlerin yeri ve sonucu ilk satırlarla sınırlamanın standart ile yaygın yazımları.

İçindekiler

Önceki üç ders hangi sütunların ve hangi satırların döneceğini belirledi. Hiçbiri satırların hangi sırayla döneceğini söylemedi. Çıktılarda görülen sıra motorun tabloyu okuma biçiminden geliyordu; aynı sorgu farklı bir plan seçildiğinde farklı sırada dönebilir.

İlişkisel modelde bir bağıntı sırasız bir küme olduğu için bu şaşırtıcı değil: sıra, verinin değil sorgunun bir özelliğidir. Sıra isteniyorsa açıkça yazılmalıdır. Bu ders sıralama yan tümcesini ve onunla birlikte anlam kazanan sınırlama yazımını kurar.

Aşağıdaki blok şemayı ve örnek veriyi kurar; dersin bütün sorguları bu blokta oluşturulan kutuphane.db dosyası üzerinde çalışır.

rm -f kutuphane.db
sqlite3 kutuphane.db <<'SQL'
CREATE TABLE sube (sube_id INTEGER PRIMARY KEY, ad TEXT NOT NULL, sehir TEXT NOT NULL);
CREATE TABLE kitap (kitap_id INTEGER PRIMARY KEY, baslik TEXT NOT NULL, yazar TEXT NOT NULL,
                    basim_yili INTEGER, sube_id INTEGER REFERENCES sube(sube_id));
CREATE TABLE uye (uye_id INTEGER PRIMARY KEY, ad TEXT NOT NULL, soyad TEXT NOT NULL,
                  eposta TEXT, kayit_tarihi TEXT NOT NULL);
CREATE TABLE odunc (odunc_id INTEGER PRIMARY KEY, kitap_id INTEGER NOT NULL REFERENCES kitap(kitap_id),
                    uye_id INTEGER NOT NULL REFERENCES uye(uye_id), alis_tarihi TEXT NOT NULL,
                    iade_tarihi TEXT);
INSERT INTO sube VALUES (1,'Merkez','Ankara'),(2,'Bahçelievler','Ankara'),
  (3,'Kadıköy','İstanbul'),(4,'Konak','İzmir');
INSERT INTO kitap VALUES (1,'Körlük','José Saramago',1995,1),(2,'Tutunamayanlar','Oğuz Atay',1972,1),
  (3,'Kum Kitabı','Jorge Luis Borges',1975,2),(4,'Yaban','Yakup Kadri',1932,2),
  (5,'Sessiz Ev','Orhan Pamuk',1983,3),(6,'Anayurt Oteli','Yusuf Atılgan',NULL,3),
  (7,'Tehlikeli Oyunlar','Oğuz Atay',1973,NULL);
INSERT INTO uye VALUES (1,'Ayşe','Demir','[email protected]','2023-02-14'),
  (2,'Mehmet','Kaya','[email protected]','2023-05-30'),(3,'Zeynep','Arslan',NULL,'2024-01-09'),
  (4,'Emre','Yıldız','[email protected]','2024-03-22'),(5,'Selin','Aydın',NULL,'2024-11-05'),
  (6,'Burak','Şahin','[email protected]','2025-01-18');
INSERT INTO odunc VALUES (1,1,1,'2025-01-10','2025-01-24'),(2,2,1,'2025-02-02','2025-02-20'),
  (3,1,2,'2025-02-11',NULL),(4,3,3,'2025-03-01','2025-03-15'),(5,4,3,'2025-03-18','2025-04-02'),
  (6,1,4,'2025-04-05','2025-04-19'),(7,5,4,'2025-04-21',NULL),(8,2,5,'2025-05-02','2025-05-30'),
  (9,7,1,'2025-05-14','2025-05-28'),(10,3,5,'2025-06-03',NULL),(11,6,2,'2025-06-11','2025-06-25'),
  (12,4,4,'2025-06-20','2025-07-04');
SQL

Tek Anahtarla Sıralama

ORDER BY yan tümcesi sıralama anahtarını alır. Yön belirtilmezse artan sıra varsayılır; ASC ve DESC yönü açıkça yazar.

sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT baslik, basim_yili FROM kitap ORDER BY basim_yili;
SQL
baslik             basim_yili
-----------------  ----------
Anayurt Oteli                
Yaban              1932      
Tutunamayanlar     1972      
Tehlikeli Oyunlar  1973      
Kum Kitabı         1975      
Sessiz Ev          1983      
Körlük             1995      

Basım yılı bilinmeyen kitap en başa geldi. Boş değerin sıralamadaki yeri kuramsal olarak belirsizdir — bilinmeyen bir sayının 1932’den büyük mü küçük mü olduğu söylenemez — bu yüzden motorlar bir varsayım yapar ve bu varsayım motora göre değişir. Bazıları boş değerleri artan sıralamada başa, bazıları sona koyar.

sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT baslik, basim_yili FROM kitap ORDER BY basim_yili DESC;
SQL
baslik             basim_yili
-----------------  ----------
Körlük             1995      
Sessiz Ev          1983      
Kum Kitabı         1975      
Tehlikeli Oyunlar  1973      
Tutunamayanlar     1972      
Yaban              1932      
Anayurt Oteli                

Yön tersine döndüğünde boş değer de tarafını değiştirdi. Yeri sorguda sabitlemek için standart bir belirteç vardır.

sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT baslik, basim_yili FROM kitap ORDER BY basim_yili NULLS LAST;
SQL
baslik             basim_yili
-----------------  ----------
Yaban              1932      
Tutunamayanlar     1972      
Tehlikeli Oyunlar  1973      
Kum Kitabı         1975      
Sessiz Ev          1983      
Körlük             1995      
Anayurt Oteli                

NULLS FIRST ve NULLS LAST belirteçleri artan sıralamada bile boş değerleri sona alabilir. Desteği motora göre değişir; desteklenmeyen motorlarda aynı sonuç, boş olup olmadığını sınayan bir ifadeyi birinci sıralama anahtarı yaparak elde edilir.

Harmanlama ve Metin Sırası

Metin sıralamasının sonucu harmanlamaya bağlıdır. Öntanımlı harmanlama karakterleri alfabetik değil, kodlarına göre karşılaştırıyorsa sonuç Türkçe alfabe sırasından ayrılır.

sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT baslik FROM kitap ORDER BY baslik;
SQL
baslik           
-----------------
Anayurt Oteli    
Kum Kitabı       
Körlük           
Sessiz Ev        
Tehlikeli Oyunlar
Tutunamayanlar   
Yaban            

Kum Kitabı, Körlük başlığından önce geldi. Türkçe alfabede ö harfi u harfinden önce gelir; burada uygulanan karşılaştırma ise karakterlerin ikili gösterimini karşılaştırdığı için u önce çıktı. Aynı etki yazar sütununda da görülür: Orhan Pamuk ile Oğuz Atay arasındaki sıra da alfabetik değildir.

Bu bir hata değil, bir yapılandırma sonucudur. Dile duyarlı sıralama isteniyorsa sütuna ya da sorguya dile özgü bir harmanlama tanımlanır; hangi harmanlamaların bulunduğu ve nasıl adlandırıldığı motora göre değişir. Kullanıcıya gösterilen listelerde bu, göz ardı edildiğinde fark edilmesi güç bir kusurdur.

Çok Anahtarlı Sıralama

Birden çok anahtar virgülle ayrılır ve sırayla uygulanır: ilk anahtarda eşit olan satırlar ikinci anahtara göre sıralanır. Her anahtarın yönü ayrı yazılır.

sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT baslik, yazar, basim_yili FROM kitap ORDER BY yazar, basim_yili DESC;
SQL
baslik             yazar              basim_yili
-----------------  -----------------  ----------
Kum Kitabı         Jorge Luis Borges  1975      
Körlük             José Saramago      1995      
Sessiz Ev          Orhan Pamuk        1983      
Tehlikeli Oyunlar  Oğuz Atay          1973      
Tutunamayanlar     Oğuz Atay          1972      
Yaban              Yakup Kadri        1932      
Anayurt Oteli      Yusuf Atılgan                

Aynı yazarın iki kitabı yeni basımdan eskiye sıralandı. DESC yalnız kendi anahtarına uygulanır; yazar sütunu artan kaldı.

Sıralama anahtarı ifade de olabilir ve sonuç sütununun sıra numarası da yazılabilir.

sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT baslik, basim_yili FROM kitap ORDER BY 2 DESC;
SQL
baslik             basim_yili
-----------------  ----------
Körlük             1995      
Sessiz Ev          1983      
Kum Kitabı         1975      
Tehlikeli Oyunlar  1973      
Tutunamayanlar     1972      
Yaban              1932      
Anayurt Oteli                

Sıra numarasıyla yazım kısa ama kırılgandır: sütun listesine bir sütun eklendiğinde sıralama sessizce başka bir sütuna kayar. Sütun adı ya da takma ad yazmak her zaman daha güvenlidir.

Belirlenimci Sıralama

ORDER BY yalnız yazıldığı anahtarlar üzerinde bir sıra kurar. Anahtarlarda eşit olan satırların kendi aralarındaki sıra tanımsızdır ve motor planı değiştirdiğinde değişebilir. Yukarıdaki sorguda yazar eşit olduğunda basım yılı ayırt ediciydi; ikisi de eşit olsaydı sonuç çalıştırmadan çalıştırmaya farklılaşabilirdi.

Sonucun her çalıştırmada aynı olması gerekiyorsa — kütüğe yazılan raporlar, sayfalanmış listeler, karşılaştırılan çıktılar — sıralama anahtarlarının sonuna benzersiz bir sütun eklenir. Birincil anahtar bu iş için doğrudan uygundur. ORDER BY yazar, kitap_id yazımı, yazarı aynı olan satırlar arasında bile tek bir sıra tanımlar.

Sınırlama

Sıralanmış bir sonucun yalnız ilk birkaç satırı isteniyorsa sınırlama yazılır. Standart yazım ile yaygın kısayol farklıdır ve bu, kursta ikinci kez karşılaşılan lehçe ayrımıdır.

sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT baslik FROM kitap ORDER BY baslik FETCH FIRST 3 ROWS ONLY;
SQL
Parse error near line 3: near "FETCH": syntax error
  SELECT baslik FROM kitap ORDER BY baslik FETCH FIRST 3 ROWS ONLY;
                             error here ---^

Standart yazım OFFSET … ROWS FETCH FIRST … ROWS ONLY biçimindedir ve burada kullanılan motor bunu tanımıyor. Motorun kabul ettiği yazım ise geniş bir kesimde ortak olan kısayoldur.

sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT baslik, basim_yili FROM kitap ORDER BY basim_yili DESC LIMIT 3;
SQL
baslik      basim_yili
----------  ----------
Körlük      1995      
Sessiz Ev   1983      
Kum Kitabı  1975      

Atlanacak satır sayısı da belirtilebilir.

sqlite3 kutuphane.db <<'SQL'
.headers on
.mode column
SELECT baslik, basim_yili FROM kitap ORDER BY basim_yili DESC LIMIT 3 OFFSET 3;
SQL
baslik             basim_yili
-----------------  ----------
Tehlikeli Oyunlar  1973      
Tutunamayanlar     1972      
Yaban              1932      

İki sorgu birlikte, üçer satırlık iki sayfa üretti. Sayfalama yazımının iki tuzağı vardır. Birincisi, sıralama yazılmadan sınırlama yazmak anlamsızdır: hangi satırların “ilk üç” olduğu tanımsız kalır ve iki ardışık sayfa aynı satırı iki kez gösterebilir. İkincisi, atlama sayısıyla sayfalama, sayfalar arasında veri değiştiğinde kayar — silinen bir satır sonraki sayfanın ilk satırını atlatır. Bu iki tuzağın ikincisi, İleri SQL kursunda anahtara dayalı sayfalama ile çözülür.

Atlama sayısının başarım maliyeti de sessizdir: motor atlanan satırları da üretip atmak zorundadır, dolayısıyla büyük atlama değerleri, sayfa numarası büyüdükçe yavaşlayan listeler üretir.

Özet

  • Sıralama verinin değil sorgunun özelliğidir; ORDER BY yazılmadan satır sırası tanımsızdır.
  • Boş değerlerin sıralamadaki yeri motora göre değişir; NULLS FIRST ve NULLS LAST belirteçleri yeri sabitler, ancak desteği de motora bağlıdır.
  • Metin sırası harmanlamaya bağlıdır; öntanımlı harmanlama Türkçe alfabe sırasını vermeyebilir.
  • Çok anahtarlı sıralamada her anahtarın yönü ayrı yazılır ve anahtarlar sırayla uygulanır.
  • Eşit anahtarlı satırların sırası tanımsızdır; belirlenimci sonuç için sıralamaya benzersiz bir sütun eklenir.
  • Sınırlamanın standart yazımı ile yaygın kısayolu farklıdır; sıralamasız sınırlama anlamsız, atlamaya dayalı sayfalama ise veri değişiminde kaygandır.

Sonraki Adım

Son üç derste boş değer üç ayrı yerde karşımıza çıktı: hesaplanmış ifadeyi boşalttı, koşulun değillemesini eksik bıraktı, sıralamada motora bağlı bir yer aldı. Bunlar tek bir kuralın sonuçlarıdır. Sonraki ders o kuralı — bilinmeyen değerin üç değerli mantığını — kurar, boş değerle çalışan işlevleri tanıtır ve liste koşulunun değillemesinde ortaya çıkan tuzağı ölçer.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat