Veritabanı Tasarımı Self-Join ve Hiyerarşik Sorgular
Konular Self-join kullanarak tablonun kendini birleştirmesi için SELECT ifadesi oluşturma ve çalıştırma Hiyerarşik sorgu kavramını yorumlama Ağaç-yapısında bir rapor oluşturma Hiyerarşik veri biçimlendirme Ağaç yapısından dallara dışlama 2
Amaç Veri modellemede, bir varlığın kendisi ile ilişkisini göstermek bazen gereklidir. SELECT worker.last_name ' works for ' manager.last_name FROM employees worker JOIN employees manager ON worker.manager_id = manager.employee_id; EMPLOYEE TABLOSU employ ee_id first_name last_name email phone_nu mber hire_date job_id salary commissi on_pct manag er_id departme nt_id 100 Steven King SKING 515.123 17-JUN-1987 AD_PRES 24000 (null) (null) 90 101 Neena Kochhar NKOCHHAR 515.123 21-SEP-1989 AD_VP 17000 (null) (null) 90 3
Amaç (devam ) Örneğin, bir çalışan aynı zamanda bir yönetici olabilir. Biz bu ilişkiyi domuz kulağı olarak isimlendiriyoruz. SELECT worker.last_name ' works for ' manager.last_name FROM employees worker JOIN employees manager ON worker.manager_id = manager.employee_id; EMPLOYEE TABLOSU employ ee_id first_name last_name email phone_nu mber hire_date job_id salary commissi on_pct manag er_id departme nt_id 100 Steven King SKING 515.123 17-JUN-1987 AD_PRES 24000 (null) (null) 90 101 Neena Kochhar NKOCHHAR 515.123 21-SEP-1989 AD_VP 17000 (null) (null) 90 4
Amaç (devam ) Gerçek çalışanlar tablosuna sahibiz, özel bir self-join ifadesi bu verilere erişmek için gereklidir. SELECT worker.last_name ' works for ' manager.last_name FROM employees worker JOIN employees manager ON worker.manager_id = manager.employee_id; EMPLOYEE TABLOSU employ ee_id first_name last_name email phone_nu mber hire_date job_id salary commissi on_pct manag er_id departme nt_id 100 Steven King SKING 515.123 17-JUN-1987 AD_PRES 24000 (null) (null) 90 101 Neena Kochhar NKOCHHAR 515.123 21-SEP-1989 AD_VP 17000 (null) (null) 90 5
Amaç (devam ) Muhtemelen veri modelinin veritabanına dönüşmeden önceki önemini şimdi daha iyi anladınız. SELECT worker.last_name ' works for ' manager.last_name FROM employees worker JOIN employees manager ON worker.manager_id = manager.employee_id; EMPLOYEE TABLOSU employ ee_id first_name last_name email phone_nu mber hire_date job_id salary commissi on_pct manag er_id departme nt_id 100 Steven King SKING 515.123 17-JUN-1987 AD_PRES 24000 (null) (null) 90 101 Neena Kochhar NKOCHHAR 515.123 21-SEP-1989 AD_VP 17000 (null) (null) 90 6
Amaç (devam ) Bu veri modelinin veritabanında var olan tablolar ile benzer olması tesadüf değildir. SELECT worker.last_name ' works for ' manager.last_name FROM employees worker JOIN employees manager ON worker.manager_id = manager.employee_id; EMPLOYEE TABLOSU employ ee_id first_name last_name email phone_nu mber hire_date job_id salary commissi on_pct manag er_id departme nt_id 100 Steven King SKING 515.123 17-JUN-1987 AD_PRES 24000 (null) (null) 90 101 Neena Kochhar NKOCHHAR 515.123 21-SEP-1989 AD_VP 17000 (null) (null) 90 7
SELF-JOIN Bir tablonun kendine birleştirilmesi için tablo iki isimle ya da takma adla verilmelidir. Bu veritabanının iki tablo olduğunu düşünmesini sağlayacaktır. EMPLOYEES(worker) Tablosu employee_id last_name manager_id 100 King 101 Kochar 100 102 De Haan 100 103 Hunold 102 104 Ernst 103 107 Lorentz 103 124 Mourgos 100 EMPLOYEES(manager) Tablosu employee_id last_name 100 King 101 Kochar 102 De Haan 103 Hunold 104 Ernst 107 Lorentz 124 Mourgos Çalışan tablosundaki manager_id Yönetici tablosundaki employee_id ile aynıdır. 8
SELF-JOIN (devam ) Bu tablo ile verinin ilişkilendirilmesi için takma adlarını seçin. EMPLOYEES(worker) Tablosu employee_id last_name manager_id 100 King 101 Kochar 100 102 De Haan 100 103 Hunold 102 104 Ernst 103 107 Lorentz 103 124 Mourgos 100 EMPLOYEES(manager) Tablosu employee_id last_name 100 King 101 Kochar 102 De Haan 103 Hunold 104 Ernst 107 Lorentz 124 Mourgos Çalışan tablosundaki manager_id Yönetici tablosundaki employee_id ile aynıdır. 9
SELF-JOIN (devam ) Burada kendi kendine birleştirme ile ilgili başka bir örnek verilmektedir. Bu grup örneğinde, enstrüman çalan grup üyeleri vardır, hem bir enstrüman çalan hem de görevi liderlik ya da başkanlık olan grup üyeleri vardır. Bu self-join yapısını göstermek için şu şekilde sorgu yazılır: SELECT chair.last_name ' is the section chair of ' player.last_name FROM band_members chair JOIN band_members player ON (player.chair_id = chair.member_id);. 10
Hiyerarşik Sorgular Hiyerarşik sorgular self-join ler ile yakından ilgilidir. Önceki sayfalarda, her çalışanın doğrudan yöneticisini görmek için self-join leri nasıl kullanabileceğimizi gördük. Hiyerarşik sorgu ile, hangi yönetici için kimlerin çalıştığını görebiliriz. Bu sorgu ile, bir şirket ya da bir bölümünün yapısını gösteren bir kuruluş şeması oluşturabilirsiniz. Bir aile ağacını düşündüğümüzde ailenin büyük üyeleri ağacın tabanına yakınken genç üyeleri ağacın dallarını temsil eder. Dallar böylece kendi dallarına sahip olur ve böylece devam eder. 11
Hiyerarşik Sorgular (devam ) Hiyerarşik sorguları kullanarak, bir tablodaki satırların arasında doğal bir hiyerarşik ilişkiye dayalı veri alabilirsiniz. Bir ilişkisel veritabanı kayıtları hiyerarşik bir şekilde saklamaz. Ancak, tek bir tablo satırları arasında hiyerarşik bir ilişki mevcut ise tree walking denilen bir süreç inşa edilerek bir hiyerarşi sağlanabilir. Bir hiyerarşik sorgu belirli bir düzen içinde bir ağacın dallarını raporlama yöntemidir. 12
Hiyerarşik Sorgu Verileri Aşağıdaki empolyee tablosundan örnek verileri inceleyin ve Steven King ile başlayan ve onunla birlikte ağaç üzerinden kimin için çalıştığını kim olduğunu görmek için hareket edin. emp_id first_name last_name email phone_number hire_date job_id salary commission_pct manager_id dept_id 100 Steven Ki ng SKING 515.123.4567 17-JUN-1987 AD_PRES 24000 (nul l) (nul l) 90 101 Neena Kochha r NKOCHHAR 515.123.4568 21-SEP-1989 AD_VP 17000 (nul l) 100 90 102 Lex De Ha a n LDEHAAN 515.123.4569 13-JAN-1993 AD_VP 17000 (nul l) 100 90 103 Al exa nder Hunol d AHUNOLD 590.423.4567 03-JAN-1990 IT_PROG 9000 (nul l) 102 60 104 Bruce Erns t BERNST 590.423.4568 21-MAY-1991 IT_PROG 6000 (nul l) 103 60 124 Kevi n Mourgos KMOURGOS 650.123.5234 16-NOV-1999 ST_MAN 5800 (nul l) 100 50 141 Trenna Ra js TRAJS 650.121.8009 17-OCT-1995 ST_CLERK 3500 (nul l) 124 50 13
Hiyerarşik Sorgu Gösterimi EMPLOYEE tablosu için organizasyon şeması aşağıdaki gibi görünecektir: 14
Hiyerarşik Sorgu Anahtar Kelimeleri Self-Join ve Hiyerarşik Sorgular Hiyerarşik sorgular kendi yeni anahtar kelimelerine sahiptir: START WITH, CONNECT BY PRIOR ve LEVEL. START WITH hangi satırın Root (Kök) olarak kullanılacağını belirler. CONNECT BY PRIOR satır arası birleştirmelerin nasıl yapıldığını açıklar. LEVEL ağacın ne kadar derinliğe sahip olacağını belirler. 15
Hiyerarşik Sorgu Anahtar Kelimeleri Örneği SELECT employee_id, last_name, job_id, manager_id FROM employees START WITH employee_id = 100 CONNECT BY PRIOR employee_id = manager_id Self-Join ve Hiyerarşik Sorgular employee_id last_name job_id manager_id 100 King AD_PRES (null) 101 Kochhar AD_VP 100 200 Whalen AD_ASST 101 205 Higgins AC_MGR 101 206 EGietz AC_ACCOUNT 205 102 De Haan AD_VP 100 103 Hunold IT_PROG 102 16 141 Rajs ST_CLERK 124
Hiyerarşik Sorgu Örneği SELECT last_name ' reports to PRIOR last_name as "Walk Top Down" FROM employees START WITH last_name = 'King' CONNECT BY PRIOR employee_id = manager_id 17 Walk Top Down King reports to Kochhar reports to King Whalen reports to Kochhar Higgins reports to Kochhar Gietz reports to Higgins De Haanreports to King Hunold reports to De Haan Ernst reports to Hunold
Hiyerarşik Sorgu LEVEL Örneği SELECT LEVEL, last_name ' reports to PRIOR last_name as "Walk Top Down" FROM employees START WITH last_name = 'King' CONNECT BY PRIOR employee_id = manager_id LEVEL hiyerarşik sorgu ile kullanılan bir sözde sütun ifadesidir. Ağacın kökünden başlayarak kaç adım olduğunu sayar. 18 LEVEL 1 King reports to Walk Top Down 2 Kochhar reports to King 3 Whalen reports to Kochhar 3 Higgins reports to Kochhar 4 Gietz reports to Higgins 2 De Haanreports to King 3 Hunold reports to De Haan 4 Ernst reports to Hunold
Hiyerarşik Sorgu Raporu Eğer yüksek seviyeden başlayıp aşağıdaki düzeylerin her birine giren ve şirket yönetim düzeylerini gösteren bir rapor oluşturmak isteniyorsa, LEVEL sözde sütun ve LPAD fonksiyonunu kullanarak tüm çalışanların seviyelerine ulaşılır. SELECT LPAD(last_name, LENGTH(last_name)+(LEVEL*2)-2,'_') AS ORG_CHART FROM employees START WITH last_name = 'King' CONNECT BY PRIOR employee_id = manager_id 19
Hiyerarşik Sorgu Çıktı Seviyesi SELECT LPAD(last_name, LENGTH(last_name)+( LEVEL*2)-2,'_') AS ORG_CHART FROM employees START WITH last_name='king' CONNECT BY PRIOR employee_id=manager_id Sağdaki sonucu gördüğünüz üzere, her satır seviye başına iki çizgi ile girintilendirilmektedir. 20
Buttom Up Hiyerarşik Sorgu SELECT LPAD(last_name, LENGTH(last_name) + (LEVEL*2) -2, '_') AS ORG_CHART FROM employees START WITH last_name = 'Grant' CONNECT BY employee_id = PRIOR manager_id Sağdaki sonucu gördüğünüz üzere, bu örnekte eşittir işaretinden sonra PRIOR anahtar sözcüğü hareket ettirilerek ve Grant START WITH yantümcesi kullanılarak Buttom Up Hiyerarşik Sorgunun nasıl oluşturulacağı gösterilmektedir. 21
Hiyerarşik Sorgu Budama Ağaç üzerinde dalları budama WHERE yantümcesi veya CONNECT BY PRIOR yantümcesi kullanılarak yapılabilir. WHERE yantümcesi kullanılırsa sadece ifadede isimlendirilen satırlar hariç kalır; CONNECT BY PRIOR yantümcesi kullanılırsa tüm dal hariç kalır. 22
Hiyerarşik Sorgu Budama (devam ) Self-Join ve Hiyerarşik Sorgular Örneğin; sonuçlarından sadece bir satır çıkarmak istiyorsanız, WHERE yantümcesini kullanmanız gerekir. Gietz in doğrudan Kochhar için çalıştığı görülür ancak öyle değildir. SELECT last_name FROM employees WHERE last_name!= 'Higgins START WITH last_name = Kochhar CONNECT BY PRIOR employee_id = manager_id 23
Hiyerarşik Sorgu Budama (devam ) Self-Join ve Hiyerarşik Sorgular Ancak bununla birlikte bir satır ve bunun altındaki tüm satırları çıkarmak istiyorsanız CONNECT BY ifadesi ile dışlama yapmak gerekir. Bu örnekte Higgins i ihraç ederken GIETZ de ihraç edilmiş olur. SELECT last_name FROM employees START WITH last_name = Kochhar CONNECT BY PRIOR employee_id = manager_id AND last_name!= 'Higgins 24