MariaDB'de veri okumak için SELECT sutunlar FROM tablo yazarsınız; satırları WHERE ile süzer, ORDER BY ile sıralar, LIMIT veya OFFSET ... FETCH ile sayısını sınırlar, DISTINCT ile tekrar eden satırları atarsınız. Yazım sırası her zaman SELECT ... FROM ... WHERE ... ORDER BY ... LIMIT şeklindedir.
Bu yazı resmî belgelerdeki SELECT, ORDER BY, LIMIT, SELECT ... OFFSET ... FETCH ve LIKE sayfalarıyla Getting Data Guide'a dayanır. Birden fazla tabloyu birleştirmek JOIN ve alt sorgular, satırları gruplayıp özetlemek GROUP BY ve toplama fonksiyonları yazısında anlatılıyor. Serinin tamamı için MariaDB öğrenme rehberine bakabilirsiniz.
SELECT ifadesinin parçaları
Belgedeki sözdizimi uzundur, ama günlük kullanımda şu parçalar yeterlidir: seçim ifadeleri, FROM, WHERE, GROUP BY, HAVING, ORDER BY ve LIMIT. Her SELECT en az bir seçim ifadesi içermelidir. Seçim ifadesi bir sütun adı, fonksiyon ve operatör kullanan herhangi bir ifade, tüm sütunlar için * ya da tek bir tablonun tüm sütunları için tablo.* olabilir.
SELECT f1,f2 FROM t1 WHERE (f3<=10) AND (f4='y');Tablo gerekmeyen hesaplamalar için FROM yazmadan SELECT 1 + 1; gibi sorgular da çalışır; belge ayrıca FROM DUAL yazımını da kabul eder. Birden fazla tablo kullanırken sütunu tablo.sutun biçiminde nitelemeniz gerekir; aynı ad iki tabloda varsa niteleme yapılmazsa MariaDB hata verir. Tırnaklama gerekiyorsa her parçayı ayrı ayrı ters tırnağa alın: `tablo`.`sutun`.
Takma adlar (AS) ve WHERE sınırı
AS takma_ad ile bir ifadeye okunaklı bir ad verebilirsiniz. Belgeye göre GROUP BY, HAVING ve ORDER BY bu takma ada başvurabilir, ama WHERE başvuramaz, çünkü WHERE seçim ifadelerinden önce değerlendirilir. GROUP BY sayfasındaki örnekte WHERE winavg > 0.2 yazmak ERROR 1054 (42S22): Unknown column 'winavg' in 'WHERE' hatasıyla sonuçlanır. Bu durumda ifadenin kendisini WHERE içine yazmanız ya da takma ada göre süzmeyi HAVING ile yapmanız gerekir.
WHERE ile süzme

WHERE, seçilecek her satır için doğru olması gereken koşulu verir; yazılmazsa tüm satırlar seçilir. Koşulda MariaDB'nin desteklediği tüm fonksiyon ve operatörler kullanılabilir, yalnızca COUNT() ve SUM() gibi toplama fonksiyonları kullanılamaz. Toplanmış değerlere göre süzme HAVING ile yapılır.
| Operatör | Anlamı | Belgedeki not |
|---|---|---|
| =, <>, <, >, <=, >= | Karşılaştırma | NULL ile karşılaştırma NULL döner |
| BETWEEN min AND max | Aralık | Uçlar dahil: min <= expr AND expr <= max |
| IN (liste) | Listede var mı | Sabit listelerde ikili arama kullanılır |
| LIKE kalıp | Kalıp eşleşmesi | % sıfır veya daha fazla, _ tek karakter |
| IS NULL, IS NOT NULL | NULL kontrolü | NULL için doğru yöntem |
| AND, OR, NOT | Mantıksal birleştirme | Parantezle önceliği açık yazın |
BETWEEN iki ucu da kapsar. Belgedeki örneklerden biri farklı tiplerin dönüştürülerek karşılaştırıldığını gösterir:
SELECT 2 BETWEEN 2 AND '3';
+---------------------+
| 2 BETWEEN 2 AND '3' |
+---------------------+
| 1 |
+---------------------+IN için belgenin altını çizdiği ayrıntı NULL davranışıdır: aranan ifade NULL ise sonuç her zaman NULL olur. Listede NULL varsa ve eşleşme bulunamazsa sonuç yine NULL olur; bu yüzden NOT IN listesine NULL karışması beklenmedik biçimde hiç satır döndürmemeye yol açabilir.
LIKE ile kalıp arama
LIKE iki joker karakter kullanır: % herhangi sayıda karakteri (sıfır dahil), _ tek bir karakteri eşler. _ bayt değil karakter eşler. Büyük ve küçük harf duyarlılığı collation'a bağlıdır: büyük-küçük harfe duyarsız bir collation'da eşleşme de duyarsızdır; adı _bin ile biten collation'lar duyarlıdır. % veya _ karakterinin kendisini aramak için ters eğik çizgiyle kaçış yapılır ya da ESCAPE ile başka bir kaçış karakteri seçilir. Belgedeki örnek:
SELECT * FROM t1 WHERE d LIKE "T%";
+----------+
| d |
+----------+
| Tuesday |
| Thursday |
+----------+Büyük metinlerde sözcük araması yapacaksanız LIKE '%kelime%' yerine tam metin indeksini değerlendirin; konu FULLTEXT arama yazısında. Metin fonksiyonlarının geri kalanı string fonksiyonları yazısında anlatılıyor.
ORDER BY ile sıralama
ORDER BY varsayılan olarak artan (ASC) sıralar, DESC azalan sıralama içindir. Virgülle birden çok ifade verilebilir: satırlar önce ilk ifadeye, eşitlik varsa ikinciye göre sıralanır. Bir tamsayı yazarsanız seçim listesindeki o sıradaki sütuna göre sıralanır. Dizeler STRCMP mantığıyla karşılaştırıldığından sondaki boşluklar yok sayılır ve sonuç collation'a göre büyük-küçük harfe duyarsız olabilir. Belgedeki örnek:
CREATE TABLE seq (i INT, x VARCHAR(1));
INSERT INTO seq VALUES (1,'a'), (2,'b'), (3,'b'), (4,'f'), (5,'e');
SELECT * FROM seq ORDER BY x,i;
+------+------+
| i | x |
+------+------+
| 1 | a |
| 2 | b |
| 3 | b |
| 5 | e |
| 4 | f |
+------+------+Takma adlarla ilgili ince bir kural vardır. Bir takma ad, FROM içindeki bir tablonun sütun adıyla aynıysa ORDER BY uyarı vermeden takma adı kullanır; tablo sütununa göre sıralamak için sütunu tablo adıyla niteleyin. GROUP BY bu durumda tersini yapar, tablo sütununu tercih eder. Belge bu yüzden takma adlara tablo sütunlarıyla aynı ad vermemeyi önerir:
CREATE TABLE items (category VARCHAR(10), color VARCHAR(10));
INSERT INTO items VALUES ('shirt','red'), ('shirt','blue'), ('hat','red');
SELECT color AS category FROM items ORDER BY category;
+----------+
| category |
+----------+
| blue |
| red |
| red |
+----------+
SELECT color AS category FROM items ORDER BY items.category;
+----------+
| category |
+----------+
| red |
| red |
| blue |
+----------+NULL değerler sıralamada en küçük kabul edilir; artan sıralamada başa, azalan sıralamada sona düşer. NULL'ları sona almak için belge ORDER BY ISNULL(col1), col1 kalıbını verir.
LIMIT ve OFFSET ile sayfalama

LIMIT n ilk n satırı döndürür. Atlama için iki eşdeğer yazım vardır: LIMIT offset, row_count ve LIMIT row_count OFFSET offset. Ofset sıfırdan başlar. Belge, hangi satırların önce geleceğini ORDER BY ile belirlemeniz gerektiğini söyler; sırasız bir LIMIT, sunucunun o anda okuduğu sıraya göre sonuç verir. Belgedeki örnekler:
CREATE TABLE members (name VARCHAR(20));
INSERT INTO members VALUES('Jagdish'),('Kenny'),('Rokurou'),('Immaculada');
SELECT * FROM members ORDER BY name LIMIT 2;
+------------+
| name |
+------------+
| Immaculada |
| Jagdish |
+------------+
SELECT * FROM members ORDER BY name LIMIT 2,1;
+-------+
| name |
+-------+
| Kenny |
+-------+İkinci sorgu alfabetik sıradaki üçüncü adı verir: ilk iki satır (ofset 0 ve 1) atlanır, sonraki bir satır döner. Web sayfalaması için sayfa başına n kayıtla k. sayfa, LIMIT n OFFSET (k-1)*n olarak düşünülebilir; ancak LIMIT bir sabit tamsayı ister, bu yüzden hesaplanan değeri uygulamanızda üretip parametre olarak geçirirsiniz.
Standart sözdizimi: OFFSET ... FETCH ve WITH TIES
MariaDB 10.6'dan itibaren SQL standardındaki OFFSET start ROWS FETCH FIRST n ROWS ONLY yazımı da desteklenir. ROW ve ROWS, FIRST ve NEXT aynı sonucu verir. Bu yazımın LIMIT'te olmayan bir özelliği WITH TIES'tır: son sırayla eşit değere sahip satırları da sonuca ekler. Belgedeki altı satırlık tabloda:
SELECT i FROM t1 ORDER BY i ASC OFFSET 1 ROWS FETCH FIRST 3 ROWS ONLY;
+------+
| i |
+------+
| 2 |
| 3 |
| 4 |
+------+
SELECT i FROM t1 ORDER BY i ASC OFFSET 1 ROWS FETCH FIRST 3 ROWS WITH TIES;
+------+
| i |
+------+
| 2 |
| 3 |
| 4 |
| 4 |
+------+WITH TIES bir ORDER BY olmadan kullanılamaz; belge bu durumda ERROR 4180 (HY000): FETCH ... WITH TIES requires ORDER BY clause to be present hatasını gösterir.
DISTINCT ile tekrarları atmak
Bir sorgu aynı değerlere sahip birden çok satır üretebilir. Varsayılan davranış (ALL) hepsini döndürmektir; DISTINCT ise seçilen sütunlar açısından aynı olan satırlardan yalnızca birini bırakır. DISTINCTROW, DISTINCT ile eş anlamlıdır. DISTINCT tüm seçim listesine uygulanır, tek bir sütuna değil; iki sütun seçerseniz iki sütunun birlikte aynı olduğu satırlar birleşir. Tüm NULL değerler bu amaçla eşit sayılır. Getting Data Guide'daki örnekte iki ayrı ISBN ile kayıtlı aynı kitap adı sonuçta bir kez görünür:
SELECT DISTINCT title
FROM books
JOIN authors USING (author_id)
WHERE name_last = 'Dostoevsky'
ORDER BY title;Farklı değerlerin sayısını bulmak için COUNT(DISTINCT sutun) kullanılır; bu GROUP BY ve toplama fonksiyonları yazısında anlatılıyor.
Sorgu süresini ve toplam satır sayısını kontrol etmek
Uzun sürebilecek sorgular için belge iki yol gösterir. SET STATEMENT max_statement_time=100 FOR SELECT ... ile tek bir sorgunun çalışma süresine sınır koyabilirsiniz. MariaDB 12.0'dan itibaren aynı amaçla /*+ MAX_EXECUTION_TIME(milisaniye) */ ipucu da kullanılabilir.
SET STATEMENT max_statement_time=100 FOR
SELECT field1 FROM table_name ORDER BY field1;Sayfalama yaparken toplam sonuç sayısını göstermek istiyorsanız kılavuz SQL_CALC_FOUND_ROWS değiştiricisini ve hemen ardından çalıştırılan SELECT FOUND_ROWS(); sorgusunu gösterir. Değer geçicidir ve yalnızca o oturuma aittir. Sorgunun nasıl çalıştığını görmek ve hızlandırmak için EXPLAIN ve ANALYZE ile indeks oluşturma yazılarına geçebilirsiniz.
Okurken satır kilitlemek: FOR UPDATE ve SKIP LOCKED
Bir satırı okuyup aynı transaction içinde güncelleyecekseniz, araya başka bir bağlantının girmesini engellemek için SELECT sonuna kilit yan tümcesi eklenebilir. Belgedeki sözdiziminde iki seçenek vardır: yazma kilidi alan FOR UPDATE ve paylaşımlı okuma kilidi alan LOCK IN SHARE MODE. İkisinin ardından kilit bekleme davranışını belirleyen WAIT n, NOWAIT veya SKIP LOCKED gelebilir.
SKIP LOCKED, kilitlenemeyen satırları sonuçtan çıkarır ve belgeye göre örtük olarak NOWAIT davranışı içerir. Bu özellik yalnızca InnoDB tablolarında uygulanır, diğer motorlarda yok sayılır. İş kuyruğu gibi senaryolarda birden çok işçinin aynı satırı almasını önlemek için kullanılan bu yaklaşımın ayrıntıları, kilit türleri ve izolasyon seviyeleriyle birlikte transaction ve izolasyon seviyeleri yazısında ele alınıyor.
START TRANSACTION;
SELECT id FROM jobs WHERE status = 'new' ORDER BY id LIMIT 1 FOR UPDATE SKIP LOCKED;Kilit bekleyen sorguları ve onları tutan bağlantıları görmek için SHOW PROCESSLIST ve KILL yazısına bakabilirsiniz. Bir başka kullanışlı ayrıntı da şudur: SELECT içinde tablo adını veritabani.tablo, sütunu da gerekirse veritabani.tablo.sutun biçiminde yazarak aynı sorguda birden çok veritabanından okuma yapabilirsiniz; bunun için o anki varsayılan veritabanını değiştirmeniz gerekmez.
Adım adım bir sorgu kurmak
Bir sorguyu sondan değil, veri kaynağından başlayarak kurmak hataları azaltır. Önce FROM ile tabloyu seçip birkaç satıra bakın, ardından WHERE koşullarını tek tek ekleyin, en sonda sıralama ve sınır koyun. Getting Data Guide da yan tümceleri bu sırayla tanıtır ve MariaDB'nin genel olarak önce WHERE, sonra ORDER BY, en son LIMIT işlediğini belirtir:
SELECT isbn, title
FROM books
WHERE author_id = 2
ORDER BY title ASC
LIMIT 5;Bu sorgu yazar numarası 2 olan kitapları başlığa göre sıralayıp ilk beşini getirir. LIMIT'i ORDER BY'dan önce yazamazsınız; sıralama tüm eşleşen satırlar üzerinde yapılır ve sınır en son uygulanır.
Sık yapılan hatalar

- ORDER BY olmadan LIMIT ile sayfalama yapmak. Satır sırası garanti olmadığından aynı kayıt iki sayfada görünebilir veya hiç görünmeyebilir.
- WHERE içinde takma ad kullanmak.
WHEREseçim ifadelerinden önce işlendiği için 1054 hatası alırsınız. - sutun = NULL yazmak. Karşılaştırma
NULLdöner, satır gelmez;IS NULLkullanın. - NOT IN listesine NULL karışması. Eşleşme yoksa sonuç
NULLolur ve sorgu beklenenden az satır verir. - LIKE aramasının her zaman büyük-küçük harfe duyarsız olduğunu varsaymak. Davranış collation'a bağlıdır;
_bincollation'lar duyarlıdır. - Takma ada tablo sütunuyla aynı adı vermek.
ORDER BYtakma adı,GROUP BYtablo sütununu kullanır ve sonuç karışır. - Gerekmediği hâlde SELECT * kullanmak. Uygulamanın ihtiyaç duyduğu sütunları açıkça yazmak, tabloya sütun eklendiğinde de sonucun değişmemesini sağlar.
Sık Sorulan Sorular
LIMIT ile OFFSET ... FETCH arasında fark var mı?
Basit sınırlamada ikisi aynı sonucu verir; belge OFFSET 1 ROWS FETCH FIRST 3 ROWS ONLY ile LIMIT 3 OFFSET 1 için aynı çıktıyı gösterir. Fark, standart yazımın WITH TIES desteğidir.
ORDER BY RAND() gibi ifadelerle sıralama yapılabilir mi?
ORDER BY belgeye göre yalnızca sütun değil fonksiyon içeren her ifadeyi kabul eder. Büyük tablolarda ifade üzerinden sıralamanın maliyetini EXPLAIN ile kontrol edin.
Sorgu sonucunu dosyaya yazabilir miyim?
Evet, SELECT ... INTO OUTFILE sonucu sunucudaki bir dosyaya biçimlendirerek yazar; tersini LOAD DATA yapar. Dosya işlemleri LOAD DATA ve mariadb-import yazısında ele alınıyor.
Sonucu dikey görmek için ne yapmalıyım?
mariadb istemcisinde sorguyu ; yerine \G ile bitirirseniz her satır alt alta sütun adlarıyla gösterilir. İstemcinin diğer kısayolları komut satırı istemcisi yazısında.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: MariaDB öğrenme rehberi · JOIN ve alt sorgular · GROUP BY · indeks oluşturma · EXPLAIN ve ANALYZE · SQL sorgu optimizasyonu