SQL ve Veritabanı Mülakat Soruları: En Çok Karşılaşılan Sorgu Senaryoları

SQL mülakat soruları nelerdir ve en çok hangi sorgu senaryoları çıkar?
SQL mülakat soruları, adayın veriyi doğru sorgulama, gruplama, birleştirme ve performansı yorumlama becerisini ölçen teknik sorulardır. En sık çıkan senaryolar şunlardır: müşteri bazında toplam, hiç sipariş vermeyenler, ikinci en yüksek değer, grup içinde ilk N kayıt, tekrar eden satırlar, kümülatif toplam ve yavaş sorgu analizi.
Bu yazıda sorgu senaryolarını tek tek ele alıyorum. Her senaryoda önce sorunun ne istediğini, ardından çözüm sorgusunu, en sonda da mülakatçının peşine düştüğü tuzağı anlatıyorum. SQL öğrenmeye sıfırdan başlıyorsanız bu yazı size uygun değil; önce temel komutları çalışmanız, sonra buraya dönmeniz daha verimli olur. Yol haritası niteliğindeki yazıları yazılım kategorisinde bulabilirsiniz.
Ben 2012'den beri dijital pazarlama tarafında çalışıyorum; ancak raporlama, kampanya verisi ve e-ticaret siparişleri yüzünden SQL her gün masamda duruyor. Ekibe yazılımcı ve veri analisti alırken de bu soruları bizzat soruyorum. Dolayısıyla aşağıdaki senaryolar kitaptan değil, gerçekten sorduğum ve yanıtlarını dinlediğim sorulardan geliyor.
SQL mülakat sorularında mülakatçı aslında neyi ölçer?
Mülakatçı yalnızca doğru sonucu görmek istemez. Asıl merak ettiği şey, sizin veriyi nasıl düşündüğünüzdür. Örneğin bir tabloda her satırın neyi temsil ettiğini, yani tablonun "tanesini" (grain) sormadan sorgu yazmaya başlıyorsanız, bu kötü bir işarettir.
Benim değerlendirme listem kabaca şöyle:
- Soruyu netleştiriyor mu: eşit değerler, NULL alanlar, tarih aralığı gibi kenar durumları soruyor mu?
- Tablonun tanesini biliyor mu: bir satır bir sipariş mi, yoksa bir sipariş kalemi mi?
- Önce basit ve doğru bir çözüm kuruyor, sonra mı iyileştiriyor?
- Sonucu kendi başına doğruluyor mu: satır sayısını kontrol ediyor mu?
- Performans sorulduğunda indeks ve sorgu planı kavramlarını biliyor mu?
Kısacası sözdizimini ezberlemek yetmez. Sesli düşünmek, varsayımlarınızı söylemek ve küçük bir örnek veriyle sonucu kafanızda test etmek, çoğu zaman kusursuz sorgudan daha çok puan kazandırır.
Senaryolarda hangi örnek tabloları kullanacağız?
Tüm örneklerde basit bir e-ticaret şeması kullanıyorum. Böylece her sorguyu aynı veri üzerinde düşünebilirsiniz. Tablolar şunlar:
- customers: id, name, city, created_at.
- orders: id, customer_id, order_date, status, total_amount.
- order_items: order_id, product_id, quantity, unit_price.
- products: id, name, category.
- employees: id, name, department_id, salary, manager_id.
Sorguları standart SQL'e yakın yazıyorum; ancak bazı fonksiyonlar PostgreSQL ve MySQL arasında farklılık gösterir. Mülakatta hangi veritabanını kullandığınızı en başta söylemeniz iyi olur. Üstelik tarih fonksiyonlarında lehçe farkı olduğunu belirtmeniz, mülakatçıya dikkatli biri olduğunuzu gösterir.
Bir not daha: orders tablosunda her satır bir sipariştir, order_items tablosunda ise her satır bir sipariş kalemidir. Bu ayrım, ilerideki senaryoların yarısında kritik rol oynuyor.
WHERE ile HAVING arasındaki farkı nasıl açıklarsınız?
Bu soru neredeyse her mülakatta ilk beş dakikada gelir. Kısa cevap şudur: WHERE, gruplama yapılmadan önce tek tek satırları süzer; HAVING ise GROUP BY sonrasında oluşan grupları süzer. Bu yüzden toplama fonksiyonu içeren bir koşulu WHERE içine yazamazsınız.
Örnek senaryo: "2025 yılında 3'ten fazla sipariş veren müşterileri listeleyin." Çözüm şöyle görünür: SELECT customer_id, COUNT(*) AS siparis_sayisi FROM orders WHERE order_date >= '2025-01-01' AND order_date < '2026-01-01' GROUP BY customer_id HAVING COUNT(*) > 3.
Burada tarih filtresi WHERE içinde, sayı filtresi HAVING içinde duruyor. Mülakatçının beklediği ek nokta şu: tarih filtresini HAVING içine taşırsanız sorgu çalışabilir ama gereksiz satırları da gruplar. Ayrıca tarih aralığını BETWEEN yerine yarı açık aralıkla yazmanız, saat bilgisi taşıyan sütunlarda son günün kaybolmasını önler. Bu küçük detayı söylediğinizde genellikle not alınır.
Her müşterinin toplam sipariş tutarını nasıl bulursunuz?
Soru basit görünür; fakat içinde iki tuzak var. İlki, hiç siparişi olmayan müşterilerin de listede görünmesi gerekip gerekmediğidir. İkincisi, toplamın NULL mu yoksa sıfır mı döneceğidir. Bu yüzden önce soruyu netleştirmenizi öneririm.
Tüm müşteriler isteniyorsa çözüm LEFT JOIN ile kurulur: SELECT c.id, c.name, COALESCE(SUM(o.total_amount), 0) AS toplam FROM customers c LEFT JOIN orders o ON o.customer_id = c.id GROUP BY c.id, c.name.
COALESCE burada sipariş olmayan müşterilerde NULL yerine sıfır döndürür. INNER JOIN kullansaydınız siparişi olmayan müşteriler sessizce kaybolurdu. Öte yandan iptal edilen siparişleri hariç tutmak isterseniz koşulu nereye yazdığınız önemlidir. Koşulu WHERE içine yazarsanız LEFT JOIN fiilen INNER JOIN'e döner. Doğru yer ON cümlesidir: LEFT JOIN orders o ON o.customer_id = c.id AND o.status <> 'cancelled'. Bu ayrımı anlatabilen aday, JOIN mantığını gerçekten kavramış demektir.
Hiç sipariş vermeyen müşterileri nasıl listelersiniz?
Bu "anti join" senaryosudur ve üç farklı çözüm yolu vardır. Mülakatçı genellikle hepsini bilip bilmediğinizi ve aralarındaki farkı sorar.
- LEFT JOIN ve IS NULL: SELECT c.* FROM customers c LEFT JOIN orders o ON o.customer_id = c.id WHERE o.id IS NULL.
- NOT EXISTS: SELECT c.* FROM customers c WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id).
- NOT IN: SELECT * FROM customers WHERE id NOT IN (SELECT customer_id FROM orders).
Asıl tuzak üçüncü yoldadır. Alt sorgu tek bir NULL değer döndürürse NOT IN hiçbir satır getirmez. Çünkü "x NOT IN (1, 2, NULL)" ifadesi bilinmeyen (unknown) sonucuna varır ve WHERE bu satırları eler. Bu davranış PostgreSQL karşılaştırma operatörleri belgesinde anlatılan üç değerli mantıktan gelir.
Bu nedenle pratikte NOT EXISTS tercih ederim. Hem NULL karşısında güvenlidir hem de çoğu modern veritabanı onu verimli bir anti join planına çevirir. Mülakatta bunu söylemeniz, ezberin ötesine geçtiğinizi gösterir.
İkinci en yüksek maaşı nasıl bulursunuz?
Klasik bir soru, ama cevabınız seviyenizi hemen ele verir. İlk akla gelen çözüm alt sorgudur: SELECT MAX(salary) FROM employees WHERE salary < (SELECT MAX(salary) FROM employees). Bu sorgu doğru çalışır ve eşit maaşları da doğru ele alır.
Mülakatçı genellikle soruyu genişletir: "Peki N'inci en yüksek maaş?" Bu noktada pencere fonksiyonuna geçmeniz beklenir. Çözüm: SELECT DISTINCT salary FROM (SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS sira FROM employees) t WHERE sira = 2.
Burada DENSE_RANK seçimini açıklamanız gerekir. İki kişi aynı en yüksek maaşı alıyorsa RANK sonraki değere 3 numarasını verir, yani ikinci sıra boş kalır. ROW_NUMBER ise eşit maaşlılardan birini keyfi olarak ikinci yapar. DENSE_RANK boşluk bırakmadan sıralar; dolayısıyla "ikinci en yüksek farklı değer" sorusunun doğru cevabı odur. Ayrıca ikinci değer yoksa ne döneceğini de sorun: boş sonuç mu, NULL mu? Bu soru sizi ayrıştırır.
Her departmanda en çok kazanan çalışanı nasıl getirirsiniz?
Bu senaryo "grup içinde ilk N" (top N per group) olarak bilinir ve orta seviye mülakatların favorisidir. Çözümün iskeleti hep aynıdır: grubu PARTITION BY ile ayırır, grubun içinde sıralar, sonra dışarıda süzersiniz.
Sorgu şöyle kurulur: WITH sirali AS (SELECT e.*, ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rn FROM employees e) SELECT * FROM sirali WHERE rn = 1.
Pencere fonksiyonunun sonucunu doğrudan WHERE içinde kullanamazsınız, çünkü WHERE pencere hesaplamasından önce çalışır. Bu yüzden CTE veya alt sorgu şarttır. Mülakatçının ikinci sorusu yine eşitlik olacaktır: aynı departmanda iki kişi aynı en yüksek maaşı alıyorsa ikisi de gelsin mi? Gelsin diyorsa ROW_NUMBER yerine RANK kullanırsınız. Pencere fonksiyonlarının mantığını PostgreSQL pencere fonksiyonu eğitiminde kısa örneklerle görebilirsiniz.
Aynı kalıp "her kategoride en çok satan 3 ürün" veya "her müşterinin son siparişi" gibi sorularda da çalışır. Kalıbı bir kez oturttuğunuzda bu soru ailesinin tamamını çözersiniz.
Tekrar eden kayıtları nasıl bulur ve silersiniz?
Bu soru iki adımdan oluşur ve ikinci adım çoğu adayı zorlar. Bulma kısmı kolaydır: SELECT email, COUNT(*) FROM customers GROUP BY email HAVING COUNT(*) > 1. Böylece hangi e-posta adresinin kaç kez tekrarlandığını görürsünüz.
Silme kısmında her gruptan bir kaydı korumanız gerekir. Genellikle en eski kaydı tutarsınız. Pencere fonksiyonuyla şöyle çözersiniz: önce ROW_NUMBER() OVER (PARTITION BY email ORDER BY created_at, id) ile her satıra sıra verirsiniz, ardından sırası 1'den büyük olan id değerlerini silersiniz.
Mülakatçının beklediği olgunluk işaretleri şunlardır:
- Silmeden önce aynı sorguyu SELECT olarak çalıştırıp etkilenen satır sayısını kontrol etmek.
- İşlemi bir transaction içinde yapmak ve sonucu gördükten sonra onaylamak.
- E-posta karşılaştırmasında büyük küçük harf ve boşluk farkını dikkate almak.
- Kalıcı çözüm olarak sütuna benzersizlik kısıtı (UNIQUE) eklemeyi önermek.
Son madde en önemlisidir. Tekrarı temizlemek bir kerelik iştir; asıl mühendislik, tekrarın bir daha oluşmasını engellemektir.
Kümülatif toplam ve hareketli ortalamayı nasıl hesaplarsınız?
Raporlama odaklı pozisyonlarda bu soru neredeyse kesin gelir. Örneğin "günlük satışların yıl başından bugüne toplamını çıkarın" denir. Önce günlük toplamı alır, sonra pencere fonksiyonuyla birikimli toplam üretirsiniz.
Sorgu: SELECT gun, ciro, SUM(ciro) OVER (ORDER BY gun) AS kumulatif FROM (SELECT CAST(order_date AS DATE) AS gun, SUM(total_amount) AS ciro FROM orders GROUP BY CAST(order_date AS DATE)) g.
Hareketli ortalama için pencere çerçevesini açıkça belirtirsiniz: AVG(ciro) OVER (ORDER BY gun ROWS BETWEEN 6 PRECEDING AND CURRENT ROW). Bu ifade son 7 satırın ortalamasını verir. Ancak burada ince bir tuzak var: satış olmayan günler tabloda hiç yoksa "son 7 satır" ile "son 7 gün" aynı şey olmaz. Deneyimli aday bunu fark eder ve eksik günleri bir takvim tablosuyla doldurmayı önerir.
Ben bu hesabı reklam raporlarında sık kullanıyorum; özellikle dijital pazarlama KPI'ları günlük dalgalandığında hareketli ortalama gerçek eğilimi gösteriyor.
Ardışık günlerde giriş yapan kullanıcıları nasıl bulursunuz?
Bu senaryo "gaps and islands" olarak bilinir ve ileri seviye mülakatlarda ayırt edici sorudur. Soru genelde şöyledir: "En az 3 gün üst üste giriş yapan kullanıcıları bulun." İlk bakışta zor görünür, ancak bilinen bir hilesi var.
Hile şudur: her kullanıcının giriş tarihlerini sıralarsınız ve tarihten sıra numarasını çıkarırsınız. Ardışık günlerde hem tarih hem sıra birer birer arttığı için fark sabit kalır. Böylece aynı farkı paylaşan satırlar bir "ada" oluşturur.
- Aynı gün birden fazla girişi tekilleştirin: SELECT DISTINCT user_id, CAST(login_at AS DATE) AS gun.
- Her kullanıcı için ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY gun) değerini hesaplayın.
- Gün eksi sıra numarası ile bir grup anahtarı üretin.
- user_id ve grup anahtarına göre gruplayıp HAVING COUNT(*) >= 3 ile süzün.
İlk adımı atlayan aday, aynı gün iki kez giriş yapan kullanıcıda seriyi bozar. Bu yüzden tekilleştirme adımını mutlaka sesli söyleyin. Tarih çıkarma sözdizimi veritabanına göre değişir; bunu da belirtmeniz yeterlidir.
Aydan aya büyümeyi LAG ile nasıl hesaplarsınız?
Bu soru, bir önceki satıra bakma becerisini ölçer. Senaryo genelde "her ayın cirosunu ve bir önceki aya göre yüzde değişimini gösterin" şeklindedir. Burada LAG fonksiyonu işinizi görür.
Önce aylık ciroyu çıkarırsınız, sonra LAG(ciro) OVER (ORDER BY ay) ile önceki ayın değerini aynı satıra taşırsınız. Yüzde değişim ise (ciro - onceki) * 100.0 / NULLIF(onceki, 0) formülüyle gelir.
Bu formülde iki detay puan kazandırır. Birincisi 100.0 ifadesidir: tam sayı bölmesi yapan veritabanlarında 100 yazarsanız sonuç yuvarlanır. İkincisi NULLIF kullanımıdır: önceki ay sıfırsa sıfıra bölme hatası yerine NULL döner. Üstelik ilk ayın önceki değeri olmadığı için orada da NULL görürsünüz; bunu hata değil, beklenen davranış olarak açıklamanız gerekir.
Aynı mantık elde tutma (retention) sorularında da işe yarar. Pazarlama tarafında bu tür tabloları sık okuyorum; dijital pazarlama raporu nasıl okunur yazısında bu karşılaştırmaların yorum kısmını anlattım.
Satırları sütuna çevirme (pivot) sorusunu nasıl çözersiniz?
Mülakatçı size "her müşterinin kategori bazında harcamasını tek satırda gösterin" diyebilir. Yani kategoriler satır değil, sütun olacaktır. Her veritabanında PIVOT komutu olmadığı için beklenen evrensel çözüm koşullu toplamadır.
Örnek: SELECT o.customer_id, SUM(CASE WHEN p.category = 'Elektronik' THEN oi.quantity * oi.unit_price ELSE 0 END) AS elektronik, SUM(CASE WHEN p.category = 'Giyim' THEN oi.quantity * oi.unit_price ELSE 0 END) AS giyim FROM orders o JOIN order_items oi ON oi.order_id = o.id JOIN products p ON p.id = oi.product_id GROUP BY o.customer_id.
Burada dikkat edilecek nokta, tutarı order_items üzerinden hesaplamaktır. Eğer orders.total_amount değerini kalemlerle birleştirip toplarsanız her sipariş, kalem sayısı kadar tekrarlanır ve toplam şişer. Bu hata mülakatlarda en sık gördüğüm yanlıştır. PostgreSQL kullanıyorsanız FILTER sözdizimini de alternatif olarak anmanız artı puan getirir.
NULL değerler SQL mülakat sorularında neden tuzak olur?
NULL, "bilinmeyen" anlamına gelir; sıfır veya boş metinle aynı şey değildir. SQL mülakat soruları arasında NULL ile ilgili kısa sorular sık çıkar, çünkü adayın dikkatini hızlıca ölçer. Aşağıdaki davranışları ezbere bilmeniz gerekir:
- NULL = NULL ifadesi doğru dönmez; kontrol için IS NULL kullanırsınız.
- COUNT(*) tüm satırları sayar, COUNT(sütun) ise NULL olanları atlar.
- AVG, NULL satırları paydaya katmaz; bu yüzden sonuç beklediğinizden yüksek çıkabilir.
- NOT IN listesinde tek bir NULL, sorgunun hiç satır döndürmemesine yol açar.
- ORDER BY içinde NULL değerlerin başta mı sonda mı duracağı veritabanına göre değişir.
Mülakatta tipik soru şudur: "COUNT(*) ile COUNT(email) neden farklı sonuç veriyor?" Cevap, e-posta alanı boş olan satırların ikinci sayımda atlanmasıdır. Bunu bir adım ileri taşıyıp "eksik veri oranını" COUNT(*) - COUNT(email) ile hesaplayabileceğinizi söylerseniz, veriyi pratikte kullandığınızı gösterirsiniz.
Yavaş çalışan bir sorguyu nasıl analiz edersiniz?
Mid seviye ve üstü pozisyonlarda bu soru neredeyse kesin gelir. Doğru cevap bir tahmin değil, bir yöntemdir. Ben adaydan şu sırayı duymak isterim: önce sorgu planına bakarım, sonra darboğazı bulurum, en son değişikliği ölçerim.
Sorgu planını EXPLAIN ile görürsünüz; EXPLAIN ANALYZE ise sorguyu gerçekten çalıştırıp gerçek süreleri ve satır sayılarını gösterir. PostgreSQL EXPLAIN belgesi tahmini ve gerçek satır sayısı arasındaki büyük farkların neden önemli olduğunu ayrıntılı anlatır.
Sık rastlanan nedenler şunlardır:
- Filtrelenen veya birleştirilen sütunda indeks olmaması.
- İndeksli sütunun bir fonksiyon içine alınması, örneğin YEAR(order_date) = 2025 yazmak.
- Gereksiz SELECT * ile geniş satırları taşımak.
- Güncel olmayan istatistikler yüzünden planlayıcının yanlış yol seçmesi.
İkinci madde klasik sorudur. Fonksiyon sütunu sarınca veritabanı indeksi doğrudan kullanamaz. Çözüm, koşulu tarih aralığı olarak yeniden yazmaktır. Bu tür yavaşlıkların web tarafındaki etkisini site hızı yazısında ele aldım.
İndeks hakkında hangi sorular sorulur?
Yavaş sorgu sorusunun devamında indeks soruları gelir. En yaygın olanı "her sütuna indeks eklesek ne olur?" sorusudur. Cevap: okuma hızlanabilir, ancak her INSERT, UPDATE ve DELETE işleminde indekslerin de güncellenmesi gerekir. Dolayısıyla yazma maliyeti artar ve disk kullanımı büyür.
İkinci yaygın soru bileşik indekslerdeki sütun sırasıdır. (customer_id, order_date) sırasıyla bir indeksiniz varsa, yalnızca customer_id ile yapılan aramalarda bu indeks işe yarar. Öte yandan yalnızca order_date ile yapılan aramada genellikle verimli kullanılamaz. Soldan başlama kuralını bir telefon rehberi benzetmesiyle anlatmak çoğu mülakatçının hoşuna gider: rehber soyada göre sıralıysa, yalnızca isme göre arama yapamazsınız.
Üçüncü soru seçicilikle ilgilidir. Yalnızca iki değer alan bir durum sütununa tek başına indeks koymak çoğu zaman fayda sağlamaz, çünkü satırların büyük kısmını yine okumanız gerekir. Bu noktada "ölçmeden karar vermem" demeniz en olgun cevaptır.
Transaction ve izolasyon seviyeleri hakkında ne bilmelisiniz?
Bu konu özellikle backend pozisyonlarında sorulur. Önce ACID kavramını tek cümleyle açıklamanız beklenir: atomiklik, tutarlılık, izolasyon ve kalıcılık. Ardından klasik senaryo gelir: "İki kullanıcı aynı anda stoktaki son ürünü satın alırsa ne olur?"
Bu senaryoda izolasyon seviyelerini bilmeniz gerekir. PostgreSQL belgesine göre varsayılan seviye Read Committed'dır. MySQL belgesine göre ise InnoDB motorunun varsayılanı Repeatable Read'dir. Bu farkı bilmek, aynı kodun iki veritabanında farklı davranabileceğini anladığınızı gösterir.
Stok sorusuna pratik cevaplar şunlardır: satırı SELECT ... FOR UPDATE ile kilitlemek, güncellemeyi koşullu yazmak (UPDATE products SET stock = stock - 1 WHERE id = 5 AND stock > 0) ve etkilenen satır sayısını kontrol etmek. Koşullu güncelleme en sade çözümdür, çünkü kontrol ve düşüşü tek adımda yapar. E-ticaret projelerinde bu hatayı canlıda görmek pahalıdır; e-ticaret danışmanlığı işlerimde stok tutarsızlığı en sık karşılaştığım sorunlardan biridir.
Normalizasyon ve tablo tasarımı sorularına nasıl yaklaşırsınız?
Bazı mülakatlarda sorgu yerine tasarım sorusu gelir: "Bir blog için yazı, yazar ve etiket tablolarını tasarlayın." Burada mülakatçı ilişki türlerini doğru kurup kurmadığınıza bakar. Yazı ile etiket arasında çoka çok ilişki olduğu için bir ara tablo (post_tags) gerekir.
Normalizasyon sorusunda üç normal formu teorik olarak saymak yerine pratik bir örnek vermenizi öneririm. Örneğin sipariş tablosunda müşterinin şehrini tekrar tekrar tutarsanız, müşteri taşındığında eski siparişlerle yeni kayıtlar çelişir. Bu, güncelleme anomalisinin somut hâlidir.
Ancak iyi bir aday, normalizasyonun her zaman hedef olmadığını da bilir. Raporlama tablolarında okuma hızını artırmak için bilinçli olarak tekrar eden veri tutabilirsiniz. Önemli olan, bu kararı neden verdiğinizi açıklamaktır. Ölçeklenen web projelerinde bu tür mimari kararların önemini micro frontend yazısında başka bir katmandan anlattım.
Hangi SQL mülakat sorusunda hangi tekniği kullanmalısınız?
Aşağıdaki tabloyu kendi mülakat notlarımdan derledim. Soru metnindeki anahtar ifadeyi görünce hangi tekniğe gideceğinizi hızlıca hatırlamanıza yarar.
| Soru ifadesi | Teknik | Sık düşülen tuzak |
|---|---|---|
| Grup bazında toplam, adetten fazla | GROUP BY ve HAVING | Toplama koşulunu WHERE içine yazmak |
| Hiç ... yapmayanlar | NOT EXISTS veya LEFT JOIN IS NULL | NOT IN ile NULL tuzağı |
| N'inci en yüksek | DENSE_RANK | Eşit değerleri atlamak |
| Her gruptaki ilk N | ROW_NUMBER ve PARTITION BY | Pencere sonucunu WHERE içinde kullanmak |
| Tekrar eden kayıtlar | GROUP BY HAVING, ROW_NUMBER | Kalıcı UNIQUE kısıtını unutmak |
| Yıl başından bugüne, birikimli | SUM OVER ORDER BY | Eksik günleri hesaba katmamak |
| Önceki aya göre değişim | LAG | Tam sayı bölmesi ve sıfıra bölme |
| Üst üste N gün | Gaps and islands | Aynı gün girişlerini tekilleştirmemek |
| Kategorileri sütun yap | CASE WHEN ile koşullu toplama | JOIN sonrası tutarı şişirmek |
Tabloyu ezberlemek yerine her satırdaki sorguyu kendi başınıza bir kez yazın. Böylece mülakatta kalıp hazır olur ve zihniniz kenar durumlarına odaklanabilir.
Canlı kodlama sırasında en sık hangi hataları yaparsınız?
Mülakatlarda gördüğüm hataların çoğu bilgi eksikliğinden değil, acelecilikten kaynaklanıyor. Aday soruyu duyar duymaz yazmaya başlıyor ve tablonun tanesini sormuyor. Sonuç olarak doğru görünen ama yanlış sayan sorgular çıkıyor.
En sık gördüğüm hatalar şunlar:
- GROUP BY içinde olmayan bir sütunu SELECT listesine eklemek.
- Sipariş tutarını kalem tablosuyla birleştirip şişirmek.
- Tarih aralığında son günü kaçırmak.
- Sonucu doğrulamadan "bitti" demek.
- Tek bir süper sorgu yazmaya çalışıp okunamaz bir yapı kurmak.
Son madde için önerim nettir: CTE kullanarak sorguyu adımlara bölün ve her adımı ayrı ayrı anlatın. Mülakatçı okunabilir bir sorguyu, zekice ama karmaşık bir sorguya tercih eder. Çünkü ekipte o sorguyu başkaları da okuyacak.
SQL mülakat soruları için nasıl bir hazırlık planı kurmalısınız?
Hazırlığı konu bazında değil, senaryo bazında yapmanızı öneririm. Yukarıdaki tablodaki her senaryo için kendi örnek verinizi oluşturun ve sorguyu en az iki farklı yolla yazın. Örneğin anti join için hem NOT EXISTS hem LEFT JOIN çözümünü deneyin ve sonuçları karşılaştırın.
Pratik bir haftalık düzen şöyle olabilir:
- İlk iki gün: GROUP BY, HAVING, JOIN ve anti join senaryoları.
- Üçüncü ve dördüncü gün: pencere fonksiyonları, sıralama, LAG ve kümülatif toplam.
- Beşinci gün: gaps and islands ve pivot soruları.
- Altıncı gün: EXPLAIN çıktısı okuma, indeks ve transaction soruları.
- Yedinci gün: süre tutarak sesli çözüm provası.
Son gün en önemlisidir. Sesli çözüm pratiği yapmadıysanız, bildiğiniz sorguyu bile mülakat heyecanında yazamayabilirsiniz. Bu plan saha tecrübeme dayalı bir başlangıç önerisidir, garanti değildir; kendi seviyenize göre süreleri uzatabilirsiniz.
SQL bilgisi yazılım dışındaki işlerde de işe yarar mı?
Kesinlikle yarar. Ben pazarlama tarafında çalışsam da reklam, sipariş ve arama verisini birleştirmek için SQL kullanıyorum. Örneğin Google Search Console verisini dışa aktarıp sipariş verisiyle eşleştirdiğinizde, hangi sayfanın gerçekten satış getirdiğini görebilirsiniz.
Bu yüzden veri analisti, pazarlama analisti ve ürün yöneticisi mülakatlarında da SQL soruları çıkıyor. Soruların zorluğu değişebilir; ancak senaryolar büyük ölçüde aynıdır: toplama, birleştirme, sıralama ve zaman karşılaştırması.
Şirketinizin web sitesi veya e-ticaret altyapısı veriyi düzgün tutmuyorsa en iyi SQL bilgisi bile anlamlı sonuç üretemez. Ölçülebilir bir altyapı kurmak istiyorsanız web tasarım hizmeti sayfama göz atabilir, sorularınız için iletişim sayfasından bana ulaşabilirsiniz.




