Short notes about SQL
Yaşayan Yazı, bir yerimden uydurduğum bir terimdir ve ileriki dönemde içeriği zenginleşebilecek ama şu anki haliyle de faydalı olabilecek yazıları belirtir.
Bu yazıda kullanılan “Employees”, “Buildings”, “movies” ve “Box Office” tabloları SQLBolt sitesinden alınmıştır.
SQL (Structured Query Language), relation database’deki verilerin sorgulanmasına, değiştirilmesine ve dönüştürülmesine olanak sağlamak için tasarlanmış bir dildir. Relation database ise iki boyutlu olan ve aralarında ilişki bulunan tablo koleksiyonudur.
Örnek tablolar üzerinden SQL senaryolarına bakalım.
Veri Okuma
Örneklerde kullandığımız tablolar:
Tüm filmleri listeleyelim;
SELECT *FROM movies;
Filmlerin yalnızca isimlerini ve yönetmenlerini listeleyelim;
SELECT title, directorFROM movies;
Filmleri en uzundan kısaya doğru listeleyelim;
SELECT *FROM moviesORDER BY length_minutes DESC;/* sıralama yönünü belirtmezsek varsayılan değer ASC'dir. */
Çıkış yılına göre ilk dört filmi listeleyelim;
SELECT *FROM moviesORDER BY year ASCLIMIT 4;/* sıralama yönünü belirtmezsek varsayılan değer ASC'dir. */
Çıkış yılına göre son dört filmi eskiden yeniye doğru listeleyelim;
SELECT *FROM moviesORDER BY year ASCLIMIT 4 OFFSET (14 - 4);/* OFFSET alınacak 4 elemanın hangi index'ten başlayacağını belirtir. */
Çıkış yılına göre son dört filmi alfabetik olarak listeleyelim;
SELECT *FROM ( SELECT * FROM movies ORDER BY year DESC LIMIT 4)ORDER BY title ASC;/* query'leri iç içe kullanabiliriz. dıştaki query'nin girdisi içerdekiquery'nin sonuç tablosudur. */
Uluslarası gişe satışı en az 455 milyon dolar olan filmleri listeleyelim;
SELECT titleFROM moviesWHERE id IN ( SELECT movie_id FROM boxoffice WHERE international_sales > 455000000);/* query'leri iç içe kullanabiliriz. dıştaki query'nin girdisi içerdekiquery'nin sonuç tablosudur. */
Filtreleme
Örneklerde kullandığımız tablolar:
Yönetmeni John Lasseter ya da Lee Unkrich olan filmleri listeleyelim;
SELECT *FROM movies WHERE director IN ("John Lasseter", "Lee Unkrich");
2005 ve 2010 yılları arasında çıkan filmleri listeleyelim;
SELECT *FROM moviesWHERE (year BETWEEN 2005 AND 2010) AND id != 7;
Toy Story serisindeki filmlerini listeleyelim;
SELECT *FROM moviesWHERE title LIKE "Toy Story%";/* ya LIKE "Toy Story%" şeklinde 0+ karakterleya da LIKE "Toy Story _" şeklinde tek bir karakterle eşleştirebiliriz. */
Toy Story serisi haricindeki tüm filmleri listeleyelim;
SELECT *FROM moviesWHERE title NOT LIKE "Toy Story%";
Tablodaki yönetmenleri listeleyelim;
SELECT DISTINCT directorFROM movies;/* normalde birden fazla filmi olan yönetmenler tabloda birden çok görülürancak DISTINCT ile yinelenen satırları tablodan kaldırıyoruz. */
Yönetmenlerin film sayılarını filtreleyip John Lasseter’ın film sayısını listeleyelim;
SELECT director, COUNT(*) AS movie_countFROM moviesGROUP BY directorHAVING director = "John Lasseter";/* verileri grupladıktan sonra filtre uygulamak için WHERE yerineHAVING kullanılır. üretilen sütunu adlandırmak için AS kullanılır.sütun adı belirtilmemişse gruptaki satır sayısını, belirtilmediysesütunda hiçbir değeri NULL olmayan satır sayısını verir. */
Birden Fazla Tabloda Çalışma
İlişkisel veritabanlarının hikmeti verinin birden fazla tabloya yayılmasıdır. Bu veriler birbirine bağlanır. Bir tablodaki PRIMARY KEY
diğer tablodaki FOREIGN KEY
’e karşılık gelir. Böylece verileri ihtiyaç duyduğumuzda diğer tablolardan toplayabiliyoruz.
Örneklerde kullandığımız tablolar:
Çalışanları oturdukları binaların kapasitesiyle birlikte listeleyelim;
SELECT *FROM employeesINNER JOIN buildings ON building_name = building;/* INNER JOIN yerine kısaltma olarak JOIN'de kullanılabilir. */
Dan B.‘nin oturduğu binanın kapasitesini listeleyelim;
SELECT capacityFROM employeesINNER JOIN buildings ON building_name = buildingWHERE name = "Dan B.";/* tablolar ayrı olduğundan bu işlem için JOIN yapmanız gerekir. */
İçerisinde yaşayan çalışan olmayan binaları listeleyelim;
SELECT *FROM buildingsLEFT JOIN employees ON building_name = buildingWHERE role IS NULL;
Henüz binaya yerleştirilmeyen çalışanları listeleyelim;
SELECT nameFROM employeesLEFT JOIN buildings ON building_name = buildingWHERE building IS NULL;
Sonucu Dönüştürme
Örneklerde kullandığımız tablolar:
Filmleri yurtdışı ve yurtiçi toplam hasılatına göre en yüksekten en düşüğe listeleyelim;
SELECT title, ((domestic_sales + international_sales) / 1000000 ) AS total_sales_as_millionsFROM moviesJOIN boxoffice ON movies.id = boxoffice.movie_idORDER BY total_sales_as_millions DESC;
Yönetmenlerin tüm filmlerinden elde ettiği hasılatı listeleyelim;
SELECT director, SUM(domestic_sales + international_sales) as cumulative_salesFROM moviesINNER JOIN boxoffice ON movies.id = boxoffice.movie_idGROUP BY director;
Küme İşlemleri
Tablolar arası küme işlemleri yapılabilir. UNION
sonuçları birbirine ekler, INTERSECT
kesişen satırlar bulur, EXCEPT
ise ilk sonuç kümesinde olup ikincisinde olmayan satırların döndürülmesini sağlar. Bu işlemleri yapabilmek için karşılanması gereken kriterler şunlardır:
- Tablolar aynı sütun sayısına sahip olmalıdır.
- Sütunlar aynı veri türüne sahip olmalıdır.
- Sonuçtaki sütunların sırası aynı olmalıdır.
Örneklerde kullandığımız tablolar:
Topluluktaki tüm vatandaşları listeleyelim;
SELECT "American" AS type, name, surname, birthdate, genderFROM american_citizensUNIONSELECT "Turkish" AS type, name, surname, birthdate, genderFROM turkish_citizens/* Tablolara özel type sütunu ekleyebiliriz. yinelenen satırları korumakiçin UNION ALL kullanılabilir. */
Topluluktaki hem Amerikan hem de Türk vatandaşı olanları listeleyelim;
SELECT name, surname, birthdate, genderFROM american_citizensINTERSECTSELECT name, surname, birthdate, genderFROM turkish_citizens/* yinelenen satırları korumak için INTERSECT ALL kullanılabilir. */
Toplulukta yalnızca Amerikan vatandaşı olanları listeleyelim;
SELECT name, surname, birthdate, genderFROM american_citizensEXCEPTSELECT name, surname, birthdate, genderFROM turkish_citizens/* yinelenen satırları korumak için EXCEPT ALL kullanılabilir. */
Toplulukta yalnızca Türk vatandaşı olanları listeleyelim;
SELECT name, surname, birthdate, genderFROM turkish_citizensEXCEPTSELECT name, surname, birthdate, genderFROM american_citizens/* yinelenen satırları korumak için EXCEPT ALL kullanılabilir. */
Tablo İşlemleri
SQL’de database schema, her bir tablonun yapısını ve tablonun her bir sütununun içerebileceği veri türlerini tanımlayan yapıdır. Tablo işlemleri de bununla ilişkilidir.
Örneklerde değindiğimiz film tablosunu oluşturur;
CREATE TABLE IF NOT EXISTS movies ( id INTEGER AUTOINCREMENT PRIMARY KEY, title TEXT NOT NULL, director TEXT NOT NULL, year INTEGER, length_minutes INTEGER);
Tabloya iki yeni çalışan ekler;
INSERT INTO moviesVALUES ("GORA", "Cem Yılmaz", 2004, 127);
INSERT INTO movies (title, director)VALUES ("AROG", "Cem Yılmaz");/* verisi olmayan satırları NULL bırakmak için sütun isimlerini verebiliriz. */
Eksik bilgi ile eklediğimiz filmi güncelleyelim;
UPDATE moviesSET year = 2008, length_minutes = 128WHERE title = "AROG"
2005 yılından önceki filmleri arşivlemek için tablodan çıkaralım;
DELETE FROM moviesWHERE year >= 7;
Film tablosunun şemasını güncelleyerek film dilini tanımlamak için sütun ekleyebiliriz;
ALTER TABLE moviesADD COLUMN language TEXT DEFAULT "English";
Film dili sütununu geri silebiliriz;
ALTER TABLE moviesDROP language;
Ve hatta film tablosunun isim değiştirebiliriz;
ALTER TABLE moviesRENAME TO movies_archive;
Tabloyu tamamen uçurmak için;
DROP TABLE IF EXISTS box_office;