Buraya kadar, yaptığımız sorgulamalarda her seferinde sadece bir tabloya erişildi. Oysa sorgulamalar aynı andan birden çok tabloya erişebildiği gibi, aynı tabloya birden fazla kez erişerek satırlara daha çeşitli yaptırımlar uygulayabilir. Aynı anda birden fazla satır ya da birden fazla tabloya erişen sorgulara katılımlı sorgu denir. Sözgelimi (daha önce oluşturduğumuz tablolardaki) tüm şehirlerin hava durumlarını ve konumlarını aynı anda listelemek istiyoruz. Bunun için weather tablosundaki tüm city sütunları ile cities tablosundaki tüm name sütunlarını karşılaştırıp, aynı olan satır çiftlerini seçmek gerekir.
| Not |
---|
Bu sadece kavramsal bir modeldir. Katılımlı sorgular, aslında, her olası satır çiftini karşılaştırmaktan biraz daha verimli bir anlamda uygulanır ama bu işlemi kullanıcı görmez.
|
Yukarıda bahsedilen işlemi şu sorgu ile elde edebiliriz:
SELECT *
FROM weather, cities
WHERE city = name;
city | tmp_lo | tmp_hi | prcp | date | name | location
---------------+--------+--------+------+------------+---------------+-----------
San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)
(2 rows)
Çıktıda dikkat edilmesi gereken iki nokta bulunmakta:
Haywrad şehri için hiçbir çıktı alınmadı dikkat edildiyse. Bunun nedeni ise cities tablosunda Hayward adlı bir şehir olmaması ve dolayısıyla JOIN bu şehri eledi. İleride bunun nasıl düzeltilebileceği üzerinde durulacak.
Bir diğer dikkat çeken nokta ise, şehirlerin adını yazan iki tane sütun olması. Bunun sebebi weather ve cities tablosunun birleştirilmesidir. Pratikte bu istenmeyen bir sonuçtur. Böyle bir durumda buna neden olan * ifadesi yerine açıkça listelenmesini istediğimiz sütunları yazarak bu işi halledebiliriz:
SELECT city, tmp_lo, tmp_hi, prcp, date, location
FROM weather, cities
WHERE city = name;
Alıştırma:
WHERE deyimi kalktığında ortaya çıkan sonucun nedenini bulmaya çalışın.
Tablolardaki tüm sütun isimleri farklı olduğundan çözümleyici hangi ismin hangi tabloya ait olduğunu bulur. Ama bunu daha da açıkça belirtmek isimler aynı olduğunda dahi sorun çıkmasını önler ve tavsiye edilen de budur:
SELECT weather.city, weather.tmp_lo, weather.tmp_hi,
weather.prcp, weather.date, cities.location
FROM weather, cities
WHERE cities.name = weather.city;
Şimdiye kadar gördüğümüz katılım sorguları ayrıca şu şekilde de yazılabilir:
SELECT *
FROM weather INNER JOIN cities ON (weather.city = cities.name);
Bu sözdizimi yukarıdaki örneklerden biri için çok kullanılan bir sözdizimi değildir, ama bundan sonraki konuları anlayabilmek için yardımcı olacağından burada gösterdik.
Şimdi Hayward kayıtlarına nasıl kavuşacağımızı işleyeceğiz. İstediğimiz şey weather tablosu üzerinde tarama yapıp, cities tablosunda bunlarla eşleşen satırları bulmak. Eğer cities tablosunda herhangi bir eşleşme bulamazsak, o sütun cities tablosu alanında boş gözükecek. Bu tür sorgulama işlemleri haricen katılım (outer join) olarak bilinir. (Şimdiye kadar gördüğümüz katılım sorgularında ise hep dahilen katılım (inner join) kullanmıştık.) Komut şöyle görünür:
SELECT *
FROM weather LEFT OUTER JOIN cities ON (weather.city = cities.name);
city | tmp_lo | tmp_hi | prcp | date | name | location
---------------+--------+--------+------+------------+---------------+-----------
Hayward | 37 | 54 | | 1994-11-29 | |
San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)
(3 rows)
Bu sorguya sola haricen katılımlı (left outer join) sorgu denir. Böyle adlandırılmasının sebebi soldaki tablonun tüm satırları en az bir kere listelenirken, sağda yer alan tablonun sadece soldaki tablonun satırlarıyla eşleşen satırlarının listelenmesidir. Bir sol-tablo satırı çıktılanırken sağ-tabloda bu satırla eşleşen bir satır yoksa, sağ-tablonun sütunları boş kalır.
Alıştırma:
Ayrıca, sağa haricen katılımlı (right outer join) ve iki yönlü haricen katılımlı (full outer join) sorgu türleri de var. Bunların ne yaptığını da siz bulmayı deneyin.
Ayrıca, bir tabloyu kendine katılımlı olarak da sorgulayabiliriz ve buna kendine katılımlı sorgu denir. Bir örnek olarak, diğer hava durumu kayıtlarının sıcaklık aralığı içinde kalan hava durumu kayıtlarını bulmak isteyelim. Yani, her weather satırının tmp_lo ve tmp_hi sütununu diğer weather satırlarının tmp_lo ve tmp_hi sütunu ile karşılaştıracağız. Bunu şu sorgu ile yapabiliriz:
SELECT W1.city, W1.tmp_lo AS low, W1.tmp_hi AS high,
W2.city, W2.tmp_lo AS low, W2.tmp_hi AS high
FROM weather W1, weather W2
WHERE W1.tmp_lo < W2.tmp_lo
AND W1.tmp_hi > W2.tmp_hi;
city | low | high | city | low | high
---------------+-----+------+---------------+-----+------
San Francisco | 43 | 57 | San Francisco | 46 | 50
Hayward | 37 | 54 | San Francisco | 46 | 50
(2 rows)
Burada katılımın sol ve sağ taraflarını ayırabilmek için weather tablosunu W1 ve W2 olarak yeniden isimlendirdik. Ayrıca, bu çeşit isimlendirmeleri aynı şeyleri uzun uzadıya yazmaktan kaçınmak için diğer sorgularda da kullanabilirsiniz. Örnek:
SELECT *
FROM weather w, cities c
WHERE w.city = c.name;
Bu tarz kısaltmalarla sıkça karşılaşacaksınız.