Temel SQL Komutları
Ders 4: Temel SQL Komutları
Section titled “Ders 4: Temel SQL Komutları”Öğrenme Hedefleri
Section titled “Öğrenme Hedefleri”Bu dersi tamamladıktan sonra:
- Temel SQL komutlarını (SELECT, INSERT, UPDATE, DELETE) kullanabileceksiniz
- JOIN çeşitlerini ve ne zaman kullanılacağını öğreneceksiniz
- Aggregation fonksiyonlarını kullanabileceksiniz
- Subquery’ler ve CTE’ler oluşturabileceksiniz
İçerik İçindekiler
Section titled “İçerik İçindekiler”- SELECT - Veri Okuma
- INSERT - Veri Ekleme
- UPDATE - Veri Güncelleme
- DELETE - Veri Silme
- JOIN - Tablo Birleştirme
- Aggregation Fonksiyonları
- Subquery’ler ve CTE’ler
SELECT - Veri Okuma
Section titled “SELECT - Veri Okuma”1. Basit SELECT
Section titled “1. Basit SELECT”-- Tüm sütunları seçSELECT * FROM users;
-- Belirli sütunları seçSELECT username, email, first_name FROM users;
-- Sütunları yeniden adlandırmaSELECT username AS kullanici_adi, email AS eposta FROM users;2. WHERE ile Filtreleme
Section titled “2. WHERE ile Filtreleme”-- EşitlikSELECT * FROM users WHERE username = 'ahmet';
-- Karşılaştırma operatörleriSELECT * FROM users WHERE id > 5;SELECT * FROM posts WHERE published = 1;
-- Mantıksal operatörlerSELECT * FROM users WHERE username = 'ahmet' AND email = 'ahmet@example.com';SELECT * FROM posts WHERE published = 1 OR user_id = 2;
-- BETWEENSELECT * FROM posts WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31';
-- INSELECT * FROM users WHERE username IN ('ahmet', 'ayse', 'mehmet');
-- NOTSELECT * FROM users WHERE username NOT IN ('test', 'demo');
-- Pattern matching (LIKE)SELECT * FROM users WHERE email LIKE '%@example.com';SELECT * FROM users WHERE username LIKE 'a%'; -- 'a' ile başlayanlarSELECT * FROM users WHERE username LIKE '%m'; -- 'm' ile bitenler
-- IS NULLSELECT * FROM users WHERE last_name IS NULL;3. Sıralama (ORDER BY)
Section titled “3. Sıralama (ORDER BY)”-- Artan sıralamaSELECT * FROM users ORDER BY username ASC;
-- Azalan sıralamaSELECT * FROM users ORDER BY created_at DESC;
-- Çoklu sıralamaSELECT * FROM posts ORDER BY published DESC, created_at ASC;4. Limit ve Offset
Section titled “4. Limit ve Offset”-- İlk 5 kayıtSELECT * FROM users LIMIT 5;
-- 5. kayıttan sonraki 10 kayıtSELECT * FROM users LIMIT 10 OFFSET 5;
-- Sayfalama (page size: 10, page: 2)SELECT * FROM posts LIMIT 10 OFFSET 10;5. DISTINCT - Tekrarlayan Kayıtları Ele
Section titled “5. DISTINCT - Tekrarlayan Kayıtları Ele”-- Benzersiz kullanıcılarSELECT DISTINCT user_id FROM posts;
-- Benzersiz kombinasyonlarSELECT DISTINCT user_id, published FROM posts;INSERT - Veri Ekleme
Section titled “INSERT - Veri Ekleme”1. Tek Kayıt Ekleme
Section titled “1. Tek Kayıt Ekleme”-- Tüm sütunlar içinINSERT INTO users (email, username, first_name, last_name)VALUES ('new@example.com', 'newuser', 'New', 'User');
-- ID belirterekINSERT INTO users (id, email, username, first_name, last_name)VALUES (100, 'new@example.com', 'newuser', 'New', 'User');2. Çoklu Kayıt Ekleme
Section titled “2. Çoklu Kayıt Ekleme”INSERT INTO users (email, username, first_name, last_name)VALUES ('user1@example.com', 'user1', 'User', 'One'), ('user2@example.com', 'user2', 'User', 'Two'), ('user3@example.com', 'user3', 'User', 'Three');3. SELECT’ten Veri Ekleme
Section titled “3. SELECT’ten Veri Ekleme”-- Başka bir tablodan veri eklemeINSERT INTO archived_users (email, username, first_name, last_name)SELECT email, username, first_name, last_nameFROM usersWHERE created_at < '2023-01-01';UPDATE - Veri Güncelleme
Section titled “UPDATE - Veri Güncelleme”1. Basit UPDATE
Section titled “1. Basit UPDATE”-- Tek sütunu güncelleUPDATE users SET first_name = 'Ahmet Can' WHERE username = 'ahmet';
-- Çoklu sütun güncellemeUPDATE usersSET first_name = 'Ahmet Can', last_name = 'Yılmaz', updated_at = CURRENT_TIMESTAMPWHERE username = 'ahmet';2. Koşullu Güncelleme
Section titled “2. Koşullu Güncelleme”-- Belirli bir koşula göre güncelleUPDATE posts SET published = 1 WHERE published = 0 AND created_at > '2024-01-01';
-- Subquery ile güncellemeUPDATE usersSET last_name = 'Updated'WHERE id IN (SELECT user_id FROM posts WHERE published = 1);DELETE - Veri Silme
Section titled “DELETE - Veri Silme”1. Basit DELETE
Section titled “1. Basit DELETE”-- Belirli bir kaydı silDELETE FROM users WHERE username = 'testuser';
-- Koşula göre silmeDELETE FROM posts WHERE published = 0 AND created_at < '2024-01-01';2. Tüm Tabloyu Temizleme
Section titled “2. Tüm Tabloyu Temizleme”-- Tüm kayıtları sil (tabloyu korur)DELETE FROM posts;
-- Tabloyu tamamen silDROP TABLE posts;JOIN - Tablo Birleştirme
Section titled “JOIN - Tablo Birleştirme”1. INNER JOIN
Section titled “1. INNER JOIN”Sadece eşleşen kayıtları getirir:
-- Kullanıcıları ve post'larını getirSELECT users.username, posts.titleFROM postsINNER JOIN users ON posts.user_id = users.id;
-- Kısa yazımı (JOIN)SELECT users.username, posts.titleFROM postsJOIN users ON posts.user_id = users.id;2. LEFT JOIN
Section titled “2. LEFT JOIN”Sol tablodaki tüm kayıtları ve sağ tablodan eşleşenleri getirir:
-- Tüm kullanıcıları ve varsa post'larını getirSELECT users.username, posts.titleFROM usersLEFT JOIN posts ON users.id = posts.user_id;
-- Post'u olmayan kullanıcıları bulSELECT users.usernameFROM usersLEFT JOIN posts ON users.id = posts.user_idWHERE posts.id IS NULL;3. RIGHT JOIN
Section titled “3. RIGHT JOIN”Sağ tablodaki tüm kayıtları ve sol tablodan eşleşenleri getirir:
SELECT users.username, posts.titleFROM usersRIGHT JOIN posts ON users.id = posts.user_id;4. FULL OUTER JOIN
Section titled “4. FULL OUTER JOIN”SQLite’da doğrudan desteklenmez, UNION ile simüle edilebilir:
SELECT users.username, posts.titleFROM usersLEFT JOIN posts ON users.id = posts.user_id
UNION
SELECT users.username, posts.titleFROM usersRIGHT JOIN posts ON users.id = posts.user_id;5. Self JOIN
Section titled “5. Self JOIN”Aynı tabloyu kendisiyle birleştirme:
-- Kullanıcıları takip edenleri bulSELECT u1.username AS user, u2.username AS followingFROM follows fJOIN users u1 ON f.follower_id = u1.idJOIN users u2 ON f.following_id = u2.id;Aggregation Fonksiyonları
Section titled “Aggregation Fonksiyonları”1. COUNT
Section titled “1. COUNT”-- Toplam kayıt sayısıSELECT COUNT(*) FROM users;
-- Belirli bir koşula göre saymaSELECT COUNT(*) FROM posts WHERE published = 1;
-- Benzersiz kayıt sayısıSELECT COUNT(DISTINCT user_id) FROM posts;2. SUM
Section titled “2. SUM”-- Toplam değerSELECT SUM(view_count) FROM posts;
-- Grup bazlı toplamSELECT user_id, SUM(view_count) as total_viewsFROM postsGROUP BY user_id;3. AVG
Section titled “3. AVG”-- OrtalamaSELECT AVG(view_count) FROM posts;
-- Grup bazlı ortalamaSELECT user_id, AVG(view_count) as avg_viewsFROM postsGROUP BY user_id;4. MIN ve MAX
Section titled “4. MIN ve MAX”-- Minimum değerSELECT MIN(created_at) FROM posts;
-- Maksimum değerSELECT MAX(view_count) FROM posts;
-- Her kullanıcının en çok görüntülenen post'uSELECT user_id, MAX(view_count) as max_viewsFROM postsGROUP BY user_id;5. GROUP BY
Section titled “5. GROUP BY”-- Her kullanıcının post sayısıSELECT user_id, COUNT(*) as post_countFROM postsGROUP BY user_id;
-- Çoklu gruplamaSELECT user_id, published, COUNT(*) as countFROM postsGROUP BY user_id, published;6. HAVING
Section titled “6. HAVING”Gruplama sonrası filtreleme:
-- Post sayısı 5'ten fazla olan kullanıcılarSELECT user_id, COUNT(*) as post_countFROM postsGROUP BY user_idHAVING COUNT(*) > 5;
-- Ortalama görüntülenme 100'den fazla olan kullanıcılarSELECT user_id, AVG(view_count) as avg_viewsFROM postsGROUP BY user_idHAVING AVG(view_count) > 100;Subquery’ler ve CTE’ler
Section titled “Subquery’ler ve CTE’ler”1. Scalar Subquery
Section titled “1. Scalar Subquery”Tek bir değer döndüren subquery:
-- En çok post'a sahip kullanıcıSELECT username, first_name, last_nameFROM usersWHERE id = ( SELECT user_id FROM posts GROUP BY user_id ORDER BY COUNT(*) DESC LIMIT 1);2. Row Subquery
Section titled “2. Row Subquery”Tek bir satır döndüren subquery:
-- Kullanıcı bilgisi ve post sayısıSELECT u.*, ( SELECT COUNT(*) FROM posts WHERE user_id = u.id ) as post_countFROM users u;3. IN ile Subquery
Section titled “3. IN ile Subquery”-- Post'u olan kullanıcılarSELECT * FROM usersWHERE id IN (SELECT DISTINCT user_id FROM posts);
-- Post'u olmayan kullanıcılarSELECT * FROM usersWHERE id NOT IN (SELECT DISTINCT user_id FROM posts);4. EXISTS ile Subquery
Section titled “4. EXISTS ile Subquery”-- Post'u olan kullanıcılar (daha performanslı)SELECT * FROM users uWHERE EXISTS ( SELECT 1 FROM posts p WHERE p.user_id = u.id);
-- Post'u olmayan kullanıcılarSELECT * FROM users uWHERE NOT EXISTS ( SELECT 1 FROM posts p WHERE p.user_id = u.id);5. CTE (Common Table Expression)
Section titled “5. CTE (Common Table Expression)”Geçici tablo oluşturma:
-- Kullanıcı post sayılarıWITH user_post_counts AS ( SELECT user_id, COUNT(*) as post_count FROM posts GROUP BY user_id)SELECT u.username, u.email, COALESCE(upc.post_count, 0) as post_countFROM users uLEFT JOIN user_post_counts upc ON u.id = upc.user_idORDER BY post_count DESC;
-- Karmaşık CTE örneğiWITH active_users AS ( SELECT DISTINCT user_id FROM posts WHERE created_at > DATE('now', '-30 days')),top_posters AS ( SELECT user_id, COUNT(*) as post_count FROM posts WHERE user_id IN (SELECT user_id FROM active_users) GROUP BY user_id ORDER BY post_count DESC LIMIT 10)SELECT u.username, u.email, tp.post_countFROM top_posters tpJOIN users u ON tp.user_id = u.id;İleri Seviye Örnekler
Section titled “İleri Seviye Örnekler”1. Window Functions
Section titled “1. Window Functions”-- Her post'un kullanıcı içindeki sıralamasıSELECT title, user_id, view_count, RANK() OVER (PARTITION BY user_id ORDER BY view_count DESC) as rankFROM posts;
-- Running totalSELECT created_at, view_count, SUM(view_count) OVER (ORDER BY created_at) as running_totalFROM posts;2. CASE Expression
Section titled “2. CASE Expression”-- Koşullu değerlendirmeSELECT title, view_count, CASE WHEN view_count > 1000 THEN 'Very Popular' WHEN view_count > 100 THEN 'Popular' WHEN view_count > 10 THEN 'Normal' ELSE 'Low' END as popularity_levelFROM posts;3. UNION ve UNION ALL
Section titled “3. UNION ve UNION ALL”-- İki sorguyu birleştir (tekrarlayanları ele)SELECT username FROM usersWHERE id < 5UNIONSELECT username FROM usersWHERE id > 10;
-- İki sorguyu birleştir (tüm kayıtlar)SELECT username FROM usersWHERE id < 5UNION ALLSELECT username FROM usersWHERE id > 10;Pratik Örnekler
Section titled “Pratik Örnekler”Örnek 1: Blog Analytics Dashboard
Section titled “Örnek 1: Blog Analytics Dashboard”-- Temel metriklerSELECT (SELECT COUNT(*) FROM users) as total_users, (SELECT COUNT(*) FROM posts) as total_posts, (SELECT COUNT(*) FROM posts WHERE published = 1) as published_posts, (SELECT COUNT(*) FROM posts WHERE created_at > DATE('now', '-7 days')) as posts_this_week;
-- En aktif yazarlarSELECT u.username, COUNT(p.id) as post_count, SUM(p.view_count) as total_viewsFROM users uJOIN posts p ON u.id = p.user_idWHERE p.created_at > DATE('now', '-30 days')GROUP BY u.idORDER BY post_count DESCLIMIT 10;
-- Popüler içeriklerSELECT p.title, u.username as author, p.view_count, p.created_atFROM posts pJOIN users u ON p.user_id = u.idWHERE p.published = 1ORDER BY p.view_count DESCLIMIT 20;Örnek 2: User Engagement
Section titled “Örnek 2: User Engagement”-- Kullanıcı etkileşim özetiWITH user_stats AS ( SELECT u.id, u.username, COUNT(DISTINCT p.id) as post_count, COALESCE(SUM(p.view_count), 0) as total_views FROM users u LEFT JOIN posts p ON u.id = p.user_id GROUP BY u.id)SELECT username, post_count, total_views, CASE WHEN post_count = 0 THEN 'Inactive' WHEN post_count < 5 THEN 'Occasional' WHEN post_count < 20 THEN 'Active' ELSE 'Power User' END as engagement_levelFROM user_statsORDER BY total_views DESC;Performans İpuçları
Section titled “Performans İpuçları”✅ İyi Pratikler
Section titled “✅ İyi Pratikler”-- ✅ Index'li sütunları WHERE'ta kullanınSELECT * FROM users WHERE email = 'user@example.com';
-- ✅ SELECT * yerine gerekli sütunları seçinSELECT username, email FROM users;
-- ✅ LIMIT kullanınSELECT * FROM posts LIMIT 100;
-- ✅ EXISTS yerine IN kullanın (bazı durumlarda)SELECT * FROM users WHERE id IN (SELECT user_id FROM posts);
-- ✅ CTE kullanın (okunabilirlik için)WITH active_users AS ( SELECT DISTINCT user_id FROM posts WHERE created_at > DATE('now', '-7 days'))SELECT * FROM users WHERE id IN (SELECT user_id FROM active_users);❌ Kötü Pratikler
Section titled “❌ Kötü Pratikler”-- ❌ Leading wildcard kullanın (index kullanılmaz)SELECT * FROM users WHERE email LIKE '%@example.com';
-- ❌ SELECT * kullanın (gereksiz veri transferi)SELECT * FROM users WHERE id = 1;
-- ❌ Funksiyonları index'li sütunlarda WHERE'ta kullanınSELECT * FROM users WHERE LOWER(username) = 'ahmet';
-- ❌ N+1 query problemi-- (Her kullanıcı için ayrı sorgu)-- Bunun yerine JOIN kullanınBu derste aşağıdaki konuları öğrendiniz:
✅ SELECT komutu ve filtreleme teknikleri ✅ INSERT, UPDATE, DELETE komutları ✅ JOIN çeşitleri ve kullanım alanları ✅ Aggregation fonksiyonları (COUNT, SUM, AVG, MIN, MAX) ✅ GROUP BY ve HAVING kullanımı ✅ Subquery’ler ve CTE’ler ✅ Performans optimizasyon teknikleri
Sonraki Ders
Section titled “Sonraki Ders”Bir sonraki dersimizde “Wrangler ile D1 Kullanımı” başlığı altında:
- Wrangler CLI komutları
- Migration yönetimi
- Local vs Remote development
- Best practices konularını inceleyeceğiz.
Kaynaklar
Section titled “Kaynaklar”Alıştırma Soruları
Section titled “Alıştırma Soruları”- INNER JOIN ve LEFT JOIN arasındaki fark nedir?
- HAVING ve WHERE arasındaki fark nedir?
- Subquery ve CTE arasında hangi durumda hangisini kullanmalısınız?
- SELECT * neden önerilmez?
- Performansı artırmak için hangi index stratejilerini kullanabilirsiniz?
Ders Süresi: 75 dakika Zorluk Seviyesi: Orta Ön Koşullar: Ders 3: İlk Veritabanını Oluşturma