ADIM ADIM SQL-2
Merhabalar arkadaşlar, Bu blog başlatmış olduğum adım adım SQL serimin ikinci yazısı olacaktır. Bu yazıdan önce eğer SQL temeliniz yoksa “ Adım Adım SQL-1 “ yazımı okumanızı öneriyorum. Çünkü bu yazımda bahsedeceğim konuları iyi anlayabilmeniz için SQL de sorgu temelimizin olması gerekmektedir.
SQL öğrenirken almış olduğum notlarımı daha kapsamlı, detaylı ve bol örnekli hale getirerek edinmiş olduğum bilgilerle sizlere de aktarmak istedim. Bu yazımda oldukça kapsamlı bir konu olduğu için SQL ‘de İlişkili Tablolardan bahsetmek isterim sizlere. O halde hadi başlayalım :)
SQL İLE İLİŞKİLİ TABLOLAR
İlişkisel veritabanları, verileri mantıksal olarak birbirine bağlı tablolar halinde saklar. Bu tablolar arasındaki ilişkiler, verilerin daha düzenli, anlamlı ve verimli bir şekilde saklanmasına ve sorgulanmasına olanak tanıyor.
İlişkili tablo türleri arasında birebir (1:1), bire çok (1:N) ve çoktan çok’a (M:N) ilişkiler bulunur. Şimdi bu türleri ve nasıl çalıştıklarını örneklerle açıklayayım:
1. Bire Bir (1:1) İlişki
Bire bir ilişkide, bir tablodaki her kayıt diğer tablodaki yalnızca bir kayıtla eşleşir. Örneğin, bir Kullanıcılar
tablosu ve her kullanıcının yalnızca bir KullanıcıDetay
bilgisi olduğunu varsayalım.
Her KullanıcıDetay
girişi, Kullanıcılar
tablosundaki bir KullanıcıID
ile ilişkilidir. Bu, her kullanıcının yalnızca bir e-posta adresi olduğu anlamına gelir.
Mesela bir sorgu örneğiyle durumu biraz daha pekiştirelim. Kullanıcıların ve onların detay bilgilerinin birleştirilmiş bir listesini almak istersek bunu yapmak için INNER JOIN
kullanmalıyız.
SELECT Kullanıcılar.KullanıcıID, Kullanıcılar.KullanıcıAdı, KullanıcıDetay.Eposta
FROM Kullanıcılar
INNER JOIN KullanıcıDetay ON Kullanıcılar.KullanıcıID = KullanıcıDetay.KullanıcıID;
Bu sorgu bizlere, her kullanıcı için kullanıcı adı ve e-posta adresini içeren bir liste döndürecektir.
Şimdi bu sorgunun nasıl çalıştığını detaylıca açıklayayım:
SELECT ifadesi sorgunun sonucunda hangi sütunların döndürüleceğini belirler. Burada Kullanıcılar.KullanıcıID
, Kullanıcılar.KullanıcıAdı
, ve KullanıcıDetay.Eposta
sütunları seçilmiştir. Bu, her kullanıcının ID'si, adı ve e-posta adresi olmak üzere üç sütunu bizlere gösterecektir.
FROM ifadesi sorgunun hangi tablo üzerinde çalıştırılacağını belirtiyor. Bu örnekte, başlangıç tablosu olarak Kullanıcılar
tablosu kullanılmıştır.
INNER JOIN
ifadesiyle, Kullanıcılar
tablosunu KullanıcıDetay
tablosu ile birleştiriyoruz. Bu birleştirme işlemi, iki tablonun da KullanıcıID
sütunları üzerinden gerçekleşmektedir. ON
anahtar kelimesiyle belirtilen koşul (Kullanıcılar.KullanıcıID = KullanıcıDetay.KullanıcıID
), hangi kayıtların birleştirileceğini tanımlamaktadır.
Peki sorgu nasıl çalışıyor?
INNER JOIN
ifadesi, her iki tabloda da eşleşen kayıtları bulur. Yani, her iki tabloda da ortak olanKullanıcıID
değerlerine sahip kayıtlar birleştirilir.- Sonuç olarak, her kullanıcının
KullanıcıID
,KullanıcıAdı
ve ona aitEposta
bilgisini içeren bir sonuç seti elde edilir. - Eğer
Kullanıcılar
tablosundaki birKullanıcıID
,KullanıcıDetay
tablosunda yoksa (veya tersi), bu kayıtlar sonuç setinde yer almaz.INNER JOIN
yalnızca iki tabloda da eşleşen kayıtları döndürür, bu yüzden her iki tabloda da karşılığı olan kayıtlar sonuçta görünür.
2. Bire Çok (1:N) İlişki
Bire çok ilişkide, bir tablodaki bir kayıt diğer tablodaki birden çok kayıtla ilişkilendirilebilir. Örneğin, bir Yazarlar
tablosu ve bir Kitaplar
tablosu olduğunu düşünelim.
Bu durumda, Ahmet adlı yazarın iki kitabı varken, Elif adlı yazarın yalnızca bir kitabı vardır. Bu, bir Yazarlar
kaydının Kitaplar
tablosunda birden çok kayıtla ilişkilendirilebileceği anlamına gelir.
Mesela bir sorgu örneğiyle bire çok ilişki durumunu biraz daha pekiştirelim. Bir yazarın yazdığı kitapları listeleyelim. Bu örnekte, Ahmet’in (YazarID = 1) yazdığı kitapları sorgulayacağız:
SELECT Yazarlar.YazarAdı, Kitaplar.KitapAdı
FROM Yazarlar
INNER JOIN Kitaplar ON Yazarlar.YazarID = Kitaplar.YazarID
WHERE Yazarlar.YazarID = 1;
YazarID’si 1 olan yazarın (Ahmet) yazdığı kitapların listesini döndürmektedir. Şimdi bu sorgunun nasıl çalıştığını detaylıca açıklayayım:
FROM Yazarlar: Sorgu, Yazarlar
tablosundan başlar. Bu, temel alınan tablodur ve buradan seçilecek veriler belirlenir.
INNER JOIN Kitaplar ON Yazarlar.YazarID = Kitaplar.YazarID: INNER JOIN
kullanarak, Yazarlar
tablosunu Kitaplar
tablosuyla birleştirir. Bu birleştirme, her iki tabloda da bulunan YazarID
sütunları üzerinden gerçekleştirilir. INNER JOIN
kullanılmasının nedeni, sadece eşleşen kayıtların (yani, her iki tabloda da YazarID
'ye sahip kayıtların) getirilmesi istenmesidir. Bu, bir yazarın yazdığı tüm kitapları bir liste olarak getirecektir.
SELECT Yazarlar.YazarAdı, Kitaplar.KitapAdı: Bu kısım, Yazarlar
tablosundaki YazarAdı
ve Kitaplar
tablosundaki KitapAdı
sütunlarını seçer. Bu şekilde, sonuç kümesi her bir kitap için yazar adını ve kitap adını içerecek şekilde oluşturulur.
WHERE Yazarlar.YazarID = 1: Sorgu, Yazarlar
tablosundaki YazarID
'si 1 olan yazarı filtreler. Bu, yalnızca belirli bir yazar (bu örnekte YazarID
'si 1 olan) ve o yazarın kitapları hakkında bilgi almak istendiğinde kullanılır.
Sonuç olarak;
Veritabanından YazarID
'si 1 olan yazarın adını ve bu yazarın yazdığı kitapların adlarını seçer. Eğer YazarID
'si 1 olan yazar birden fazla kitap yazmışsa, bu kitapların her biri için bir satır olacak şekilde birden fazla satır döndürebilir. INNER JOIN
kullanıldığı için, eğer YazarID
'si 1 olan yazarın hiç kitabı yoksa, sorgu hiçbir sonuç döndürmez (çünkü INNER JOIN
yalnızca eşleşen kayıtlarda çalışır ve eşleşme olmazsa sonuç döndürmez).
3. Çoktan Çoka (M:N) İlişki
Çoktan çoka ilişkilerde, bir tablodaki kayıtlar diğer tablodaki birden çok kayıtla ilişkilendirilebilir ve bu ilişki iki yönlüdür. Genellikle, bu tür ilişkileri yönetmek için üçüncü bir “arası” tablo kullanılır. Örneğin, Öğrenciler
ve Dersler
tabloları arasında bir ilişki düşünelim:
Bu durumda, Zeynep hem Matematik hem de Fizik derslerine kayıtlıyken, Mehmet yalnızca Fizik dersine kayıtlıdır. Bu, Öğrenciler
ve Dersler
arasındaki çoktan çoka ilişkiyi yöneten ÖğrenciDers İlişkisi
tablosu ile sağlanır.
Mesela bir sorgu örneğiyle çoktan çoka ilişki durumunu biraz daha pekiştirelim. Öğrenciler ve onların kaydoldukları dersler arasındaki çoktan çoka ilişkiyi sorgulayalım. Örneğin, her öğrenci için kaydolduğu dersleri listeleyelim.
SELECT Öğrenciler.ÖğrenciAdı, Dersler.DersAdı
FROM Öğrenciler
INNER JOIN ÖğrenciDers İlişkisi ON Öğrenciler.ÖğrenciID = ÖğrenciDers İlişkisi.ÖğrenciID
INNER JOIN Dersler ON ÖğrenciDers İlişkisi.DersID = Dersler.DersID;
Bu sorgu, öğrencilerin her biri için kaydoldukları derslerin listesini döndürecektir. Çoktan çoka ilişkiler, bu ara tabloyla (ÖğrenciDers İlişkisi) yönetilir ve bu sorgu, ilişkili verileri bir araya getirmek için INNER JOIN
kullanır.
Şimdi bu sorgunun nasıl çalıştığını detaylıca açıklayayım:
Bu sorgu, Öğrenciler
, ÖğrenciDers İlişkisi
(bu örnekte ara tablo olarak kullanılıyor) ve Dersler
tablolarını kullanarak, öğrencilerin aldıkları derslerin listesini elde etmek için tasarlanmıştır. Bu sorgu, çoktan çoka bir ilişkiyi ele alır, çünkü bir öğrenci birden fazla ders alabilir ve bir ders de birden fazla öğrenci tarafından alınabilir.
FROM Öğrenciler: Sorgu, Öğrenciler
tablosundan başlar. Bu, ilk referans noktasıdır ve sorgu bu tablodaki verilere dayanarak işlem yapar.
INNER JOIN ÖğrenciDers İlişkisi ON Öğrenciler.ÖğrenciID = ÖğrenciDers İlişkisi.ÖğrenciID: İlk olarak, Öğrenciler
tablosu, ÖğrenciDers İlişkisi
ara tablosu ile INNER JOIN
kullanılarak birleştirilir. Bu birleştirme işlemi, her iki tabloda da ortak olan ÖğrenciID
sütunları üzerinden gerçekleştirilir. Bu adım, her öğrencinin hangi dersleri aldığını belirlemek için gerekli olan öğrenci-ders ilişkisini kurar.
INNER JOIN Dersler ON ÖğrenciDers İlişkisi.DersID = Dersler.DersID: Ardından, ÖğrenciDers İlişkisi
tablosu Dersler
tablosu ile birleştirilir. Bu ikinci INNER JOIN
işlemi, derslerin hangi dersler olduğunu anlamak için, ara tablodaki DersID
ile Dersler
tablosundaki DersID
'yi eşleştirir.
SELECT Öğrenciler.ÖğrenciAdı, Dersler.DersAdı: Sorgu sonucunda, Öğrenciler
tablosundan ÖğrenciAdı
ve Dersler
tablosundan DersAdı
seçilir. Bu, sonuç kümesinin her satırında bir öğrenci adı ve bu öğrencinin aldığı bir ders adını içerecek şekilde düzenlenmesini sağlar.
Her bir ilişki türünü tablolar ve sorgu örnekleriyle ilk olarak detaylıca açıkladım. Sorguların nasıl bir mantıkla çalıştığını, tabloların ve verilerin birbirleriyle nasıl ilişki kurduklarını açıkladım. Şimdi ise daha detaylı sorgu örnekleri ve sonuç tabloları ile konuyu iyice pekiştirelim istiyorum.
Bire Bir İlişki Örneği: Kullanıcılar ve Kullanıcı Profilleri
Bu örnekte, her kullanıcının yalnızca bir profil bilgisi olduğunu düşünelim.
CREATE TABLE Kullanici (
KullaniciID INT PRIMARY KEY,
KullaniciAdi VARCHAR(50)
);
CREATE TABLE Profil (
ProfilID INT PRIMARY KEY,
KullaniciID INT,
DogumTarihi DATE,
Sehir VARCHAR(50),
FOREIGN KEY (KullaniciID) REFERENCES Kullanici(KullaniciID)
);
İlk olarak tablolarımızı oluşturuyoruz.
INSERT INTO Kullanici (KullaniciID, KullaniciAdi) VALUES (1, 'Ayşe');
INSERT INTO Kullanici (KullaniciID, KullaniciAdi) VALUES (2, 'Eren');
INSERT INTO Profil (ProfilID, KullaniciID, DogumTarihi, Sehir) VALUES (1, 1, '1990-05-01', 'İstanbul');
INSERT INTO Profil (ProfilID, KullaniciID, DogumTarihi, Sehir) VALUES (2, 2, '1992-08-15', 'Ankara');
Ardından Insert Into ifadesini kullanarak tablolarımıza verilerimizi ekliyoruz.
Şimdi ise bir kullanıcı ve onun profil bilgisini birleştirerek sorgulama yapalım:
SELECT K.KullaniciAdi, P.DogumTarihi, P.Sehir
FROM Kullanici K
JOIN Profil P ON K.KullaniciID = P.KullaniciID;
| KullaniciAdi | DogumTarihi | Sehir |
|--------------|-------------|----------|
| Ayşe | 1990-05-01 | İstanbul |
| Eren | 1992-08-15 | Ankara |
Bu sonuç tablosu, her bir kullanıcının adı, doğum tarihi ve şehir bilgilerini içermektedir. İlk satırda “Ayşe” kullanıcısının profil bilgileri bulunmakta ve doğum tarihi 1990–05–01 ve şehri İstanbul olarak belirtilmektedir. İkinci satırda ise “Eren” kullanıcısının profil bilgileri bulunmakta ve doğum tarihi 1992–08–15 ve şehri Ankara olarak belirtilmektedir.
Bire Çok İlişki Örneği: Yazarlar ve Kitaplar
CREATE TABLE Yazar (
YazarID INT PRIMARY KEY,
YazarAdi VARCHAR(100)
);
CREATE TABLE Kitap (
KitapID INT PRIMARY KEY,
KitapAdi VARCHAR(100),
YazarID INT,
FOREIGN KEY (YazarID) REFERENCES Yazar(YazarID)
);
Yazar ve Kitap tablolarımızı oluşturduk.
INSERT INTO Yazar (YazarID, YazarAdi) VALUES (1, 'Orhan Pamuk');
INSERT INTO Yazar (YazarID, YazarAdi) VALUES (2, 'Elif Şafak');
INSERT INTO Kitap (KitapID, KitapAdi, YazarID) VALUES (1, 'Kara Kitap', 1);
INSERT INTO Kitap (KitapID, KitapAdi, YazarID) VALUES (2, 'Masumiyet Müzesi', 1);
INSERT INTO Kitap (KitapID, KitapAdi, YazarID) VALUES (3, 'Aşk', 2);
Tablolara veri ekledik. Şimdi de bir yazarın yazdığı kitapları sorgulayalım:
SELECT Y.YazarAdi, K.KitapAdi
FROM Yazar Y
JOIN Kitap K ON Y.YazarID = K.YazarID;
| YazarAdi | KitapAdi |
|--------------|------------------|
| Orhan Pamuk | Kara Kitap |
| Orhan Pamuk | Masumiyet Müzesi |
| Elif Şafak | Aşk |
Bu sonuç tablosu, her bir yazarın adı ve yazdığı kitapların adlarını içermektedir. İlk satırda “Orhan Pamuk” yazarının iki kitabı, “Kara Kitap” ve “Masumiyet Müzesi” bulunmaktadır. İkinci satırda “Elif Şafak” yazarının ise “Aşk” adında bir kitabı bulunmaktadır.
Çoktan Çoka İlişki Örneği: Öğrenciler ve Dersler
Bu örnekte, öğrencilerin birden fazla derse kayıt olabileceği ve bir dersin birden fazla öğrencisi olabileceğini düşünelim.
CREATE TABLE Ogrenci (
OgrenciID INT PRIMARY KEY,
OgrenciAdi VARCHAR(100)
);
CREATE TABLE Ders (
DersID INT PRIMARY KEY,
DersAdi VARCHAR(100)
);
CREATE TABLE OgrenciDers (
OgrenciID INT,
DersID INT,
FOREIGN KEY (OgrenciID) REFERENCES Ogrenci(OgrenciID),
FOREIGN KEY (DersID) REFERENCES Ders(DersID),
PRIMARY KEY (OgrenciID, DersID)
);
Ogrenci, Ders ve OgrenciDers tablolarımızı oluşturduk.
INSERT INTO Ogrenci (OgrenciID, OgrenciAdi) VALUES (1, 'Leyla');
INSERT INTO Ogrenci (OgrenciID, OgrenciAdi) VALUES (2, 'Mecnun');
INSERT INTO Ders (DersID, DersAdi) VALUES (1, 'Matematik');
INSERT INTO Ders (DersID, DersAdi) VALUES (2, 'Fizik');
INSERT INTO OgrenciDers (OgrenciID, DersID) VALUES (1, 1);
INSERT INTO OgrenciDers (OgrenciID, DersID) VALUES (1, 2);
INSERT INTO OgrenciDers (OgrenciID, DersID) VALUES (2, 1);
Tablolara verileri girdik. Şimdi ise bir dersi alan öğrencileri sorgulayalım:
SELECT D.DersAdi, O.OgrenciAdi
FROM OgrenciDers OD
JOIN Ogrenci O ON OD.OgrenciID = O.OgrenciID
JOIN Ders D ON OD.DersID = D.DersID;
Ortaya çıkacak olan sonuç tablosu ise aşağıdaki gibi olacaktır:
| DersAdi | OgrenciAdi |
|-----------|------------|
| Matematik | Leyla |
| Fizik | Leyla |
| Matematik | Mecnun |
her bir dersin adı ile o dersi alan öğrencilerin adlarını içermektedir. İlk satırda “Matematik” dersini alan öğrenci “Leyla”, ikinci satırda yine “Fizik” dersini alan “Leyla” öğrencisi ve üçüncü satırda “Matematik” dersini alan “Mecnun” öğrencisi bulunmaktadır.
Bir başka örnek daha vereceğim ve konuya son örneğimle nokta koyacağım.
İlk olarak sorgu yapmadan önce tablolarımızı ve tablolar arası ilişki diyagramlarını göstermek itiyorum:
Şimdi sorgumuzu yazalım:
Select NOTID,OGRAD + ' ' + OGRSOYAD AS 'AD SOYAD', DERSAD, SINAV1, SINAV2, SINAV3, ORTALAMA, DURUM From TBLNOTLAR
INNER JOIN TBLDERSLER
ON TBLNOTLAR.DERS = TBLDERSLER.DERSID
INNER JOIN TBLOGRENCILER
ON TBLNOTLAR.OGRENCI = TBLOGRENCILER.OGRID
Şimdi bu sorguda neler yapılmış haydi gelin detaylıca inceleyelim:
TBLNOTLAR
adlı tablonun içeriğini sorgularken, bu tablodaki öğrenci ve ders bilgilerini kullanarak ilgili öğrencinin aldığı derslerin notlarını ve ders adlarını görüntülüyoruz.
FROM TBLNOTLAR: Sorgu, TBLNOTLAR
tablosundan başlar. Bu tablo, öğrencilerin aldıkları derslere ve bu derslerde aldıkları notlara ilişkin bilgileri içerir.
INNER JOIN TBLDERSLER ON TBLNOTLAR.DERS = TBLDERSLER.DERSID: İlk INNER JOIN
işlemi, TBLDERSLER
tablosunu TBLNOTLAR
tablosuyla birleştirir. Bu birleştirme, her bir notun TBLDERSLER
tablosundaki ders bilgileri ile eşleştirilmesini sağlar. İki tablo arasındaki ilişki, DERSID
alanının eşleşmesine dayanır.
INNER JOIN TBLOGRENCILER ON TBLNOTLAR.OGRENCI = TBLOGRENCILER.OGRID: İkinci INNER JOIN
işlemi, TBLOGRENCILER
tablosunu TBLNOTLAR
tablosuyla birleştirir. Bu birleştirme, her bir notun TBLOGRENCILER
tablosundaki öğrenci bilgileri ile eşleştirilmesini sağlar. İki tablo arasındaki ilişki, OGRID
alanının eşleşmesine dayanır.
SELECT NOTID, OGRAD + ‘ ‘ + OGRSOYAD AS ‘AD SOYAD’, DERSAD, SINAV1, SINAV2, SINAV3, ORTALAMA, DURUM: Son olarak, istenen sütunlar seçilir ve gerekli düzenlemeler yapılır. Öğrencinin adı ve soyadı birleştirilerek AD SOYAD
olarak yeni bir sütun oluşturulur. Bu sütun, öğrencinin adını ve soyadını tek bir sütun olarak gösterir. Ayrıca, ders adı, sınav notları, ortalama ve durum gibi bilgiler de seçilir.
Bu şekilde, TBLNOTLAR
tablosundaki her bir not, hem ders bilgileri (TBLDERSLER
tablosu) hem de öğrenci bilgileri (TBLOGRENCILER
tablosu) ile eşleştirilir. Bu sayede, her notun hangi ders ve hangi öğrenciye ait olduğu görüntülenir. Sonuç tablosu da örnek olarak aşağıdaki gibi bir görüntü de olacaktır:
Oldukça detaylı örnekler ve görsellerle SQL de Tablolar arası ilişki türlerini detaylıca anlatmaya çalıştım. Uzun bir konu olduğu için bu yazımı tamamen bu konuya ayırmak istedim. Unutmayalım ki SQL de tablolar arası ilişki kurmak çok önemlidir ve sıklıkla kullanılır. En çok kullanılan ilişki türü de Birden Çoka ilişki türüdür. Umarım detaylıca aktarabilmişimdir sizlere konuyu. Okuduğunuz için teşekkür ederim. Diğer yazılarımda görüşmek üzere…
İyi Kodlamalar :)