Kendinden birleşmelerin açıklaması


87

Kendi kendine katılma ihtiyacını anlamıyorum. Lütfen birisi bunları bana açıklayabilir mi?

Basit bir örnek çok yardımcı olacaktır.

Yanıtlar:


99

Kendinden birleşimi iki özdeş tablo olarak görüntüleyebilirsiniz. Ancak normalleştirmede, tablonun iki kopyasını oluşturamazsınız, böylece kendi kendine birleşen iki tablonun simülasyonunu yaparsınız.

İki tablonuz olduğunu varsayalım:

Tablo emp1

Id Name Boss_id            
1   ABC   3                   
2   DEF   1                   
3   XYZ   2                   

Tablo emp2

Id Name Boss_id            
1   ABC   3                   
2   DEF   1                   
3   XYZ   2                   

Şimdi, her çalışanın adını patronunun adıyla birlikte almak istiyorsanız:

select c1.Name , c2.Name As Boss
from emp1 c1
    inner join emp2 c2 on c1.Boss_id = c2.Id

Bu, aşağıdaki tabloyu çıkaracaktır:

Name  Boss
ABC   XYZ
DEF   ABC
XYZ   DEF

1
Bu örnekte kimin patron olduğunu bulamıyorum. Exp, iyi ve anlaşılması kolay olsa da.
MAC

2
left joinBence patronu olmayan çalışanı (veya patronu) dışarıda bırakmamak daha iyi olur; en iyi köpek!
Rockin4Life33

Emp1 c1 yerine emp c1'den mi olmalı? @pointlesspolitics
Rohit Singh

22

Kendisine referans veren bir tablonuz olduğunda oldukça yaygındır. Örnek: Her çalışanın bir yöneticisi olabileceği ve tüm çalışanları ve yöneticisinin adını listelemek istediğiniz bir çalışan tablosu.

SELECT e.name, m.name
FROM employees e LEFT OUTER JOIN employees m
ON e.manager = m.id

18

Kendi kendine birleştirme, bir tablonun kendisiyle birleşmesidir.

Yaygın bir kullanım durumu, tablonun aralarında hiyerarşik bir ilişki olan varlıkları (kayıtları) saklamasıdır . Örneğin, kişi bilgilerini (İsim, DOB, Adres ...) içeren ve Babanın (ve / veya annenin) kimliğinin yer aldığı bir sütun içeren bir tablo. Sonra küçük bir sorgu ile

SELECT Child.ID, Child.Name, Child.PhoneNumber, Father.Name, Father.PhoneNumber
FROM myTableOfPersons As Child
LEFT OUTER JOIN  myTableOfPersons As Father ON Child.FatherId = Father.ID
WHERE Child.City = 'Chicago'  -- Or some other condition or none

aynı sorguda hem çocuk hem de baba (ve ikinci bir kendine katılma vb. ile anne ve hatta büyük ebeveyn vb.) hakkında bilgi alabiliriz.


5

Diyelim ki bir masanız var users, şöyle ayarlayın:

  • Kullanıcı kimliği
  • Kullanıcı adı
  • kullanıcı yöneticisinin kimliği

Bu durumda, hem kullanıcının bilgilerini hem de yöneticinin bilgilerini tek bir sorguda almak isterseniz, şunu yapabilirsiniz:

SELECT users.user_id, users.user_name, managers.user_id AS manager_id, managers.user_name AS manager_name INNER JOIN users AS manager ON users.manager_id=manager.user_id

4

Tablonuz kendi kendine referans veriyorsa yararlıdırlar. Örneğin, bir sayfa tablosu için her sayfanın bir nextve previousbağlantısı olabilir. Bunlar, aynı tablodaki diğer sayfaların kimlikleri olabilir. Bir noktada art arda üç sayfa elde etmek istiyorsanız , aynı tablonun sütununa sahip nextve previoussütunlarında iki self-birleşim yaparsınız id.


4

EmployeeAşağıda açıklandığı gibi adlandırılan bir tablo hayal edin . Tüm çalışanların aynı zamanda çalışan olan bir yöneticisi vardır (belki de manager_id değeri boş olan CEO hariç)

Table (Employee): 

int id,
varchar name,
int manager_id

Ardından, tüm çalışanları ve yöneticilerini bulmak için aşağıdaki seçimi kullanabilirsiniz:

select e1.name, e2.name as ManagerName
from Employee e1, Employee e2 where
where e1.manager_id = e2.id

4

Bir tablonun kendisine başvurma yeteneği olmadan, hiyerarşideki katman sayısı kadar hiyerarşi seviyeleri için çok sayıda tablo oluşturmamız gerekir. Ancak bu işlevsellik mevcut olduğu için, masayı kendisine katarsınız ve sql ona iki ayrı tablo gibi davranır, böylece her şey tek bir yerde güzelce saklanır.


ama şimdi (umarız) öz referans mevcut olmasaydı ne olacağını anlıyorsunuz.
Eugene

4

Yukarıda belirtilen cevapların dışında (çok iyi açıklanmış olan), Self Join kullanımının kolayca gösterilebilmesi için bir örnek eklemek istiyorum. Aşağıdaki özniteliklere sahip MÜŞTERİLER adında bir tablonuz olduğunu varsayalım: Müşteri Kimliği, MüşteriAdı, İletişimAdı, Şehir, Ülke. Şimdi "aynı şehirden" olanları listelemek istiyorsunuz. ŞEHİR temelinde onlara katılabilmemiz için bu tablonun bir kopyasını düşünmeniz gerekecek. Aşağıdaki sorgu ne anlama geldiğini açıkça gösterecektir:

SELECT A.CustomerName AS CustomerName1, B.CustomerName AS CustomerName2, 
A.City
FROM Customers A, Customers B
WHERE A.CustomerID <> B.CustomerID
AND A.City = B.City 
ORDER BY A.City;

3
+1 Bu cevap çok önemlidir, çünkü SO'da cevabı "kendi kendine katılma kullanın" olan pek çok SQL sorusu vardır, ki insanlar açık (hiyerarşik) bir öz referansları olmadığında bunu göremezler.
JimmyB

1
Bu w3schools'tan makarna kopyası olsa bile, yukarıdaki cevabın kendi kendine birleşmeyi değil, farklı olan iç birleştirmeyi açıkladığını düşünüyorum.
George K

3

Burada birçok doğru cevap var, ancak aynı derecede doğru olan bir varyasyon var. Birleştirme koşullarınızı WHERE yan tümcesi yerine join deyimine yerleştirebilirsiniz.

SELECT e1.emp_id AS 'Emp_ID'
  , e1.emp_name AS 'Emp_Name'
  , e2.emp_id AS 'Manager_ID'
  , e2.emp_name AS 'Manager_Name'
FROM Employee e1 RIGHT JOIN Employee e2 ON e1.emp_id = e2.emp_id

Bazen e1.manager_id> e2.id istediğinizi unutmayın

Her iki senaryoyu da bilmenin avantajı, bazen bir ton WHERE veya JOIN koşuluna sahip olmanız ve kodunuzu okunabilir tutmak için diğer maddeye kendi kendine katılma koşullarınızı yerleştirmek istemenizdir.

Bir Çalışanın yöneticisi olmadığında ne olacağını kimse ele almadı. Huh? Sonuç kümesine dahil edilmezler. Ya yöneticisi olmayan çalışanları dahil etmek istiyorsanız, ancak yanlış kombinasyonların geri gelmesini istemiyorsanız?

Bu yavruyu dene;

SELECT e1.emp_id AS 'Emp_ID'
   , e1.emp_name AS 'Emp_Name'
   , e2.emp_id AS 'Manager_ID'
   , e2.emp_name AS 'Manager_Name'
FROM Employee e1 LEFT JOIN Employee e2 
   ON e1.emp_id = e2.emp_id
   AND e1.emp_name = e2.emp_name
   AND e1.every_other_matching_column = e2.every_other_matching_column

1
Hm, köpek yavrusu, neden "eşittir" yerine "büyüktür" e katılıyorsunuz?
Marcel

1
Selam. Bazı örneklerde "FROM xxx, yyy WHERE" ve bazı diğer "xxx FROM xxx JOIN yyy WHERE" kullanıldığını gördüm. Lütfen farkı açıklar mısınız?
skan

@Skan Bu gerçekten güzel bir soru. Kısa cevap, bunun eski steno yöntem olduğu ve kullanımdan kaldırılacak olmasıdır. On + yıl önce okulda kullandım ve pratikte nadiren görüyorum. İşte bulabildiğim en kısa açıklama: bidn.com/blogs/KathiKellenberger/sql-server/2875/…
BClaydon

1

Bir kullanım durumu, bir veritabanında yinelenen kayıtları kontrol etmektir.

SELECT A.Id FROM My_Bookings A, My_Bookings B
WHERE A.Name = B.Name
AND A.Date = B.Date
AND A.Id != B.Id

Yinelenenleri bulmak için GROUP BY ve HAVING yan tümcesi kullanmak çok daha hızlıdır. SEÇ adı, e-posta, COUNT ( My_Bookings GRUBU TARAFINDAN adı DAN), tarih HAVING COUNT ( )> 1
George K

@GeorgeK True. Sanırım bu sadece belirsiz bir eşleşme için gerekli (TRIM (LOWER (Ad)) ile gruplamanın ötesinde) ve katı eşitlik için değil.
Molossus spondee

1

Kendi kendine birleştirme, tablonun verilerini kendisiyle değerlendirmeniz gerektiğinde kullanışlıdır. Bu, aynı tablodaki satırları ilişkilendireceği anlamına gelir.

Syntax: SELECT * FROM TABLE t1, TABLE t2 WHERE t1.columnName = t2.columnName

Örneğin, İlk Ataması mevcut atama eşit olan çalışanların adlarını bulmak istiyoruz. Bunu self join ile şu şekilde çözebiliriz.

SELECT NAME FROM Employee e1, Employee e2 WHERE e1.intialDesignationId = e2.currentDesignationId

0

Bu, bağlantılı bir listenin / ağacın veritabanı eşdeğeridir; burada bir satır, bir kapasitede başka bir satıra referans içerir.


Aslında, birden fazla satırın bir "ebeveyn" e başvurabildiği göz önüne alındığında, bu da bir ağaç olabilir, örneğin çalışan-> yönetici gibi sık sık anılan örnekte olduğu gibi.
NVRAM

Basit bir benzetme yapmaya çalışıyordum, ama evet bir ağaç da işe yarayabilir.
Unsliced

-4

İşte meslekten olmayanlar açısından kendi kendine katılmanın açıklaması. Kendi kendine birleştirme, farklı bir birleştirme türü değildir. Diğer birleştirme türlerini (İç, Dış ve Çapraz Birleşimler) anladıysanız, kendi kendine birleştirme basit olmalıdır. INNER, OUTER ve CROSS JOINS'de 2 veya daha fazla farklı masaya katılırsınız. Ancak, kendi kendine katılma modunda itslef ile aynı masaya katılırsınız. Burada 2 farklı tablonuz yok, ancak aynı tabloyu tablo takma adlarını kullanarak farklı bir tablo olarak ele alıyoruz. Bu hala net değilse, aşağıdaki youtube videolarını izlemenizi tavsiye ederim.

Bir örnekle Self Join

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.