7.1 SELECT

<< İçindekileri Görüntülemek İçin Tıklayın >>

Yer:  Teknik Kılavuzlar > IVEDI SQL Kullanıcı Kılavuzu > 7. Veri işleme (DML) >

7.1 SELECT

Yan tümceler derleyicinin ayrıştırdığı sırada yazılır:

[WITH <ad> [(<sütunlar>)] AS ( <select> ) [, …]]
SELECT [FIRST <n>] [SKIP <n>] [DISTINCT | ALL] <seçim listesi>
  [FROM <kaynak> [, <kaynak> …] <join zinciri>]
  [WHERE <koşul>]
  [GROUP BY <ifadeler>]
  [HAVING <koşul>]
  [{UNION [ALL | DISTINCT] | INTERSECT | EXCEPT} <select>]
  [ORDER BY <sıralama>]
  [OFFSET <n> [ROWS]] [FETCH {FIRST|NEXT} [<n>] ROWS ONLY]
  [ROWS <m> [TO <n>]]
  [INTO :<değişken> [, …]]

7.1.1 Seçim listesi

  • * — yalnızca listenin tamamı bu tek belirteçten oluşuyorsa.
  • <takma ad>.* ya da <tablo>.*.
  • Herhangi bir ifade, ardından [AS] <takma ad> (AS isteğe bağlıdır).
Not

SELECT ALL <ifade> ayrıştırılır ve tüketilir: ALL varsayılan davranıştır (yinelenen satırlar korunur), yazılması hiçbir şeyi değiştirmez. Yinelenenleri elemek için DISTINCT kullanılır.

7.1.2 FROM kaynakları

KaynakDurum
Temel tablo, görünümçalışır
Türetilmiş tablo ( SELECT … )çalışır — alt sorgu özel bir bellek tablosuna maddeleştirilir
CTE başvurusu (WITH)çalışır — her başvuru kendi kopyasını maddeleştirir
DUALçalışır; FROM hiç yazılmazsa kendiliğinden eklenir
Dış tabloçalışır
Eşadlı (synonym)çalışır — hedefine çözülür
LATERAL ( SELECT … )çalışır — alt sorgu o anki dış satırı okur ve her satır için yeniden maddeleştirilir
JSON_TABLE( … )çalışır — örtülü LATERAL sayılır, belgesi önceki kaynağın bir sütunu olabilir
Seçilebilir yordam, tablo tipli değişkençalışır — satırlar bir kez okunup bellek tablosuna maddeleştirilir; yalnızca SELECT ve MERGE … USING kaynağı olabilir, öteki DML deyimlerinde çalışma zamanında reddedilir
Sınır

Türetilmiş tabloya sütun takma ad listesi verilemez: d(a, b) yazımı ayrıştırılmaz, yalnızca tek bir takma ad kabul edilir. Sütunlar alt sorgunun içinde adlandırılır.

7.1.3 Birleştirmeler (JOIN)

BiçimDurum
[INNER] JOIN … ON …çalışır
LEFT [OUTER] JOIN … ON …çalışır
Virgülle ayrılmış FROM listesiçalışır (kartezyen çarpım)
CROSS JOINçalışır
RIGHT [OUTER] JOINayrıştırılır, yerel motorda çalışma zamanında reddedilir
FULL [OUTER] JOINayrıştırılır, yerel motorda çalışma zamanında reddedilir
NATURAL [LEFT] JOINçalışır — ortak adlı sütunlar üzerinden eşleşir
JOIN … USING (<sütunlar>)ayrıştırılmaz
[NATURAL] PIVOT JOINçalışır — derleme anında türetilmiş tabloya LEFT JOIN olarak yeniden yazılır (aşağıda)

ON yan tümcesi INNER/LEFT/RIGHT/FULL için zorunludur; NATURAL birleştirmede ON yazılamaz (hata). NATURAL ile CROSS birleşmez. RIGHT/FULL için geçici çözüm, tarafları değiştirip LEFT kullanmaktır; SQL metnine çeviren motorlarda (Firebird/PostgreSQL) ikisi de yazıldığı gibi hedefe geçer.

Not

NATURAL JOIN sağ tarafın her sütunu için, o ana kadar birleştirilen kaynaklarda aynı adı taşıyan ilk sütunla eşitlik koşulu kurar (niteliksiz sütun başvurusunun kuralı). Aynı ad birden çok kaynakta varsa kritik bir sorguda birleştirme koşulunu açıkça yazmak daha güvenlidir.

PIVOT JOIN

<sol> [NATURAL] PIVOT JOIN <ilişki> [<takma ad>] [ON <koşul>]
  VALUES <toplam>( <ifade> | * ) COLUMNS <ifade> [LABELS <ifade>] [AS <pivot takma adı>]

Sol satır başına, COLUMNS ifadesinin verideki her ayrı değeri için bir sütun üretilir; sütunun değeri, ON ile eşleşen ve o değeri taşıyan satırlar üzerinden VALUES toplamıdır. Eşleşmeyen sol satırın sütunları NULL'dur (LEFT JOIN davranışı), NULL COLUMNS değeri sütun olmaz. Etiket verilmezse değerin metni sütun adıdır ve tanıtıcı değilse tırnakla yazılır (p."2020"). ON, VALUES ve COLUMNS zorunludur; NATURAL PIVOT ON almaz. Ayrı değerler derleme anında okunur: hazırlanmış bir deyim sonradan eklenen değerleri görmez.

select r.region, p."2020", p."2021"
  from pv_region r
  pivot join pv_sales s on s.region = r.region
    values sum(s.amount) columns s.yr as p;

select s.y2020, s.y2021
  from pv_region r
  pivot join pv_sales s on s.region = r.region
    values count(*) columns s.yr labels 'Y' || s.yr;   --// pivot takma adı yoksa ilişkinin takma adı kullanılır

7.1.4 Gruplama ve pencereler

GROUP BY düz bir ifade listesidir. Pencere fonksiyonları gruplanmamış satırlar üzerinde, GROUP BY çıktısı üzerinde ve UNION dallarının içinde çalışır (bkz. bölüm 5.6).

Sınır

GROUPING SETS, CUBE, ROLLUP ve GROUPING() ayrıştırılmaz. Adlandırılmış pencere (WINDOW w AS (…)) yoktur.

GROUP BY <n> 1 tabanlı seçim öğesi konumudur ve o öğeye çözülür. Anahtar bir çıktı sütunu takma adı da olabilir; kapsamda aynı adla çözülen bir nesne (bir girdi sütunu, bir değişken) varsa o kazanır — PostgreSQL'in kuralı. Aynısı ORDER BY için de geçerlidir.

Not

Anahtar bir sabite gidiyorsa — doğrudan sabit bir ifadeyse ya da konum sabit bir seçim öğesine düşüyorsa — deyim derlenir ama gruplamaz/sıralamaz; motor bunu bir uyarıyla bildirir (“GROUP BY key 2 is a constant and does not group”).

7.1.5 Sıralama

ORDER BY <ifade | sütun | sıra no> [ASC | DESC] [NULLS FIRST | NULLS LAST] [, …]

Sıra numaraları (1 tabanlı) desteklenir ve aralık denetimi derleme anında yapılır. Sıralama kararlıdır; varsayılanda NULL en büyük sayılır. Harmanlama, anahtar ifadesinin bildirilen harmanlamasıdır, yoksa geçerli veritabanınınki.

Sınır

Bir UNION üzerinde ORDER BY <ifade> reddedilir; çıktı sütunu adıyla ya da sıra numarasıyla sıralama çalışır.

7.1.6 Satır sınırlama

BiçimDurum
FIRST <n> / SKIP <n>çalışır
OFFSET <n> [ROWS]çalışır
FETCH {FIRST|NEXT} [<n>] ROWS ONLYçalışır (<n> yazılmazsa 1)
ROWS <m> [TO <n>]çalışır — ROWS m = FIRST m; ROWS m TO n = m'den n'e satırlar (1 tabanlı, kapsayıcı)
LIMIT <n>ayrılmış sözcük ama tüketilmez
Dikkat

Üç yazım karşılıklı dışlayıcıdır: FIRST/SKIP, OFFSET/FETCH ve ROWS aynı sorguda birlikte kullanılamaz. Bir UNION dalı FIRST/SKIP kullanabilir ama kendi ORDER BY'ını ya da OFFSET/FETCH/ROWS'unu kullanamaz; bunlar sorgunun sonuna yazılır ve bütün sonuca uygulanır.

7.1.7 Küme işlemleri

UNION, UNION ALL, UNION DISTINCT, INTERSECT ve EXCEPT çalışır. Küme işleçleri depolama motorundan bağımsızdır: dalların satırları motorlardan okunur, birleştirme ve karşılaştırma motorun kendi katmanında yapılır.

INTERSECT iki tarafta da bulunan satırları verir, EXCEPT soldakinden sağdakileri düşer. İkisi de sonucu tekilleştirir:

--// A = {1, 2, 2, 3}   B = {2, 3, 4}
select v from a intersect select v from b order by v;   --// 2, 3
select v from a except    select v from b order by v;   --// 1
select v from a union     select v from b order by v;   --// 1, 2, 3, 4
select v from a union all select v from b order by v;   --// 1, 2, 2, 2, 3, 3, 4

Dal uygunluğu derleme anında denetlenir: dalların sütun sayısı eşit olmalı ve her sütun ilk dalın sütununa atanabilir olmalıdır. Tip ailesi değişen bir atama uyarı alır.

Sınır

INTERSECT ile UNION/EXCEPT aynı sorguda karışamaz; karışık yazım adlı bir hata alır. Nedeni SQL:2011 7.13'ün öncelik kuralıdır: INTERSECT ötekilerden daha sıkı bağlar, yani A UNION B INTERSECT C = A UNION (B INTERSECT C). Bu lehçede sorgu ifadeleri düz ve soldan sağa değerlendirilir ve parantezli sorgu ifadesi yoktur, dolayısıyla o gruplama yazılamaz. Tek tür işleç kullanan her sorgu — yalnızca UNION, yalnızca INTERSECT, yalnızca EXCEPT — sınırsız uzunlukta zincirlenebilir ve standartla aynı sonucu verir.

INTERSECT ALL ve EXCEPT ALL yoktur (adlı red). Onlar sonucu tekilleştirmez, çokluğu min(m,n) ve max(0, m-n) yapar. MINUS (Oracle yazımı) bir anahtar sözcük değildir ve tanınmaz; karşılığı EXCEPT'tir.

7.1.8 Tek satır okuma: SELECT … INTO

Bu biçim yalnızca PSQL içinde geçerlidir ve INTO en sona yazılır:

select v from t where k = 3 into :x;      -- doğru
select 40 + 2 into :x;                   -- FROM'suz biçim de çalışır
Dikkat

Alışıldık select v into :x from t yazımı sözdizimi hatasıdır; hata INTO'da değil, INTO listesinden sonra kalan metinde bildirilir.

Anlambilim: eşleşen satır yoksa hedef değişken dokunulmadan kalır ve hata verilmez; ikinci bir satır gelirse MULTIPLE_ROWS_SELECTED yükseltilir. Atama konumsaldır ve derleme anında tip denetiminden geçer.