Ana içeriğe geç
Modül 5 · Ders 2 ders 4Kurstaki 18/57~10 min
Modül dersleri (2/4)

Self-JOIN: kendi içinde bir tablo

Bazen aşmak istediğiniz ilişki iki kişi arasında değildir farklı tablolar, ancak aynı tablonun satırları arasında. Tipik örnek: bir "kategori → alt kategori" hiyerarşisi; burada hem ebeveyn hem de çocuk satırlardır parent_id ile bağlanan aynı categories tablosu.

Bir satırı (çocuk) ve "onun" diğer satırını (ebeveyn) birlikte okumak için kendi kendine katılma: aynı tablo FROM'de iki kez görünür; farklı takma adlar.

Sözdizimi

SQL
SELECT colonne
FROM   tabella AS alias_a
JOIN   tabella AS alias_b ON alias_a.foreign_key = alias_b.id;

Takma ad zorunludur: AS a / AS b atlanırsa PostgreSQL'in name veya id yazdığımızda iki kopyadan hangisini kastettiğimizi bilmenin yolu.

SQL
-- Ogni sotto-categoria con il nome della categoria padre:
SELECT child.name  AS subcategory,
       parent.name AS category
FROM   categories AS child
JOIN   categories AS parent ON child.parent_id = parent.id;

Düz İngilizce okuyun: _"child adlı categories satırlarını alın ve her biri için id olan ebeveyn adlı categories satırını bulun. parent_id çocuğun".

Sonuç, kök kategorileri hariç tutar (parent_id = NULL olanlar) çünkü bir INNER JOIN eşleşmeyen satırları atlıyor. Dahil etmek istiyorsanız onlar için LEFT JOIN kullanın.

"Kökleri de korumak" için SOL ile kendi kendine birleşme

SQL
-- Tutte le categorie, con nome del padre o NULL se sono radice:
SELECT child.name AS category,
       parent.name AS parent
FROM   categories AS child
LEFT JOIN categories AS parent ON child.parent_id = parent.id;

Artık parent = NULL ile 9 satır (veri kümesindeki her kategori) elde edersiniz 3 kök için.

Kendi kendine katılmayla toplama

"Her biri kaç çocuk yapıyor?" sorusunu sormak için GROUP BY ile çok iyi birleşiyor ebeveyn var":

SQL
SELECT p.name AS parent_category,
       COUNT(c.id) AS children
FROM   categories AS p
LEFT JOIN categories AS c ON c.parent_id = p.id
WHERE  p.parent_id IS NULL          -- solo le radici
GROUP BY p.name
ORDER BY p.name;

İki önemli ayrıntıya dikkat edin:

  1. WHERE p.parent_id IS NULL JOIN'den önce filtreler: yalnızca kökleri "soldaki tablo" olarak kullanın.
  2. COUNT(c.id) (COUNT(*) değil) çocuğu olmayan kökler için 0 değerini döndürür, oysa COUNT(*) LEFT JOIN satırı nedeniyle 1 değerini döndürür BOŞ.

Kendin dene

Egzersiz#sql.m5.l2.e1
Denemeler: 0Yükleniyor…

Kendi kategorisine göre (ebeveyn_id NOT NULL ile kategori), alt kategorinin çoğu adı ve kategorinin adı. Due kolonne: alt kategori, kategori. Kategori başına sıralama, alt kategori başına poi.

Düzenleyici yükleniyor…
İpucu göster

Self-JOIN'in koşulu child.parent_id = parent.id'dir.

3 denemeden sonra çözüm mevcut

Alıştırmayı gözden geçirin

Egzersiz#sql.m5.l2.e2
Denemeler: 0Yükleniyor…

Her kategoriye göre (parent_id IS NULL), çoğu isim ve alt kategori sayısı. Due kolonne: isim, çocuklar. İsim başına Ordina. Olası bir radice senza figlie con 0'ı ekleyin.

Düzenleyici yükleniyor…
İpucu göster

LEFT JOIN kategorilerde iki kez (ebeveyn için p, çocuk için c takma adı). Çocuksuz köklerde 0 elde etmek için COUNT(*) değil COUNT(c.id) kullanın.

3 denemeden sonra çözüm mevcut