0Pricing
SQL Interview Prep · Ders

Ardışık Takvim Günlerini Tespit Etme

Kesintisiz gün dizilerini bulmak için tarih aritmetiğini ve satır numaralarını kullanın.

Ardışık Takvim Günlerini Tespit Etme, CoddyKit'te ücretsiz bir SQL Interview Prep dersidir. Bu, 4 dersinin 1. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, SQL Interview Prep öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. SQL Interview Prep kursu toplamda 4 dersten oluşur.

Mülakat Senaryosu

Mülakatçılar seri sorularını sever; çünkü bu sorular pencere işlevlerini ve tarih aritmetiğini gerçekten anlayıp anlamadığınızı ortaya çıkarır. Tipik bir soru şöyledir: "Bir kullanıcı giriş tarihleri tablosu verildiğinde, kesintisiz ardışık takvim günlerinin her bir serisini bulun."

İlk akla gelen yaklaşım, her satırı bir sonraki satırla karşılaştıran bir kendisiyle birleştirmedir; ancak bu yöntem büyük tablolarda maliyeti hızla artırır ve ifade edilmesi de hantaldır. Profesyonel yanıt, boşluklar ve adalar tekniğini kullanır. Bu derste satır numaraları ve tarih çıkarma ile ardışık günleri temiz bir biçimde algılamayı öğreneceksiniz.

Örnek Veriler

Bu ders boyunca, kullanıcının etkin olduğu her gün için bir satır içeren logins tablosunu kullanacağız. Yinelenenlerin önceden kaldırıldığı, yani her takvim günü için bir giriş bulunduğu varsayılır.

  • user_id — giriş yapan kişi
  • login_date — bir DATE değeri

1. kullanıcı için tarihler 1, 2 ve 3 Ocak, ardından bir boşluk, sonra da 6 ve 7 Ocak'tır. İki seri bekleriz: 3 günlük bir seri ve 2 günlük bir seri.

SELECT * FROM logins ORDER BY user_id, login_date;
-- user_id | login_date
--    1    | 2024-01-01
--    1    | 2024-01-02
--    1    | 2024-01-03
--    1    | 2024-01-06
--    1    | 2024-01-07

Temel Fikir

Ardışık günlerle ilgili her problemi çözen püf nokta şudur: Satırları tarihe göre sıralayıp her birine sıralı bir satır numarası verirseniz, ardışık günlerden oluşan herhangi bir seride tarih ile satır numarası arasındaki fark sabit kalır.

Neden mi? Ardışık her günde hem tarih hem de satır numarası tam olarak 1 artar; bu nedenle aralarındaki fark değişmez. Bir boşluk oluştuğunda tarih sıçrar, ancak satır numarası sıçramaz; böylece sabit değer bozulur ve yeni bir grup başlar.

Farkı Görmek

1. kullanıcı için bunu elle inceleyelim. ROW_NUMBER değerleri 1, 2, 3, 4, 5 olarak sayar. Satır numarasını (gün cinsinden) tarihten çıkarıp sonucu izleyin.

  • 1 Ocak − 1 = 31 Aralık
  • 2 Ocak − 2 = 31 Aralık
  • 3 Ocak − 3 = 31 Aralık
  • 6 Ocak − 4 = 2 Ocak
  • 7 Ocak − 5 = 2 Ocak

İlk üç satır 31 Aralık değerini, son iki satır ise 2 Ocak değerini paylaşır. Bu ortak çıpa değeri bizim grup anahtarımızdır.

ROW_NUMBER Ekleme

İlk somut adım, her kullanıcı için ayrı bölümlenmiş ve tarihe göre sıralanmış bir satır numarası eklemektir; böylece seriler kullanıcı sınırlarını hiçbir zaman aşmaz.

PARTITION BY user_id sayacı her kullanıcı için yeniden başlatır; ORDER BY login_date ise dizinin takvim sırasını izlemesini garanti eder.

SELECT
  user_id,
  login_date,
  ROW_NUMBER() OVER (
    PARTITION BY user_id
    ORDER BY login_date
  ) AS rn
FROM logins;

Grup Çıpasını Hesaplama

Şimdi login_date değerinden rn gün çıkarın. PostgreSQL'de bir tarih değerinden tam sayı gün sayısını doğrudan çıkarabilirsiniz. Sonuç, her adayı tanımlayan sabit çıpadır.

rn diğer adını, onu tanımlayan aynı SELECT içinde kullanamayacağınızı unutmayın; bu nedenle önceki sorguyu bir CTE veya alt sorguyla sarmalamanız gerekir.

WITH numbered AS (
  SELECT
    user_id,
    login_date,
    ROW_NUMBER() OVER (
      PARTITION BY user_id ORDER BY login_date
    ) AS rn
  FROM logins
)
SELECT
  user_id,
  login_date,
  login_date - rn AS grp
FROM numbered;

Adaları Gruplama

Çıpa elimizdeyken her ardışık seri aynı grp değerini paylaşır. user_id ve grp değerlerine göre gruplayıp her serinin başlangıcını, bitişini ve uzunluğunu elde etmek için toplulaştırın.

  • MIN(login_date) — serinin ilk günü
  • MAX(login_date) — serinin son günü
  • COUNT(*) — serideki gün sayısı
WITH numbered AS (
  SELECT user_id, login_date,
    ROW_NUMBER() OVER (
      PARTITION BY user_id ORDER BY login_date
    ) AS rn
  FROM logins
)
SELECT
  user_id,
  MIN(login_date) AS streak_start,
  MAX(login_date) AS streak_end,
  COUNT(*)        AS streak_len
FROM numbered
GROUP BY user_id, login_date - rn
ORDER BY user_id, streak_start;

SQL Lehçeleri Arasındaki Farklar

Tarih aritmetiği söz dizimi değişiklik gösterir. Kapsamlı bilginizi göstermek için bunu mülakatlarda belirtin.

  • PostgreSQL: login_date - rn (tarihten tam sayı gün çıkarma)
  • MySQL: DATE_SUB(login_date, INTERVAL rn DAY)
  • SQL Sunucusu: DATEADD(day, -rn, login_date)

İşlem mantığı aynıdır; yalnızca işlev adları değişir. Taşınabilir zihinsel model şudur: "Her tarihi konumuna göre geriye kaydırın; böylece temiz bir seri tek bir sabit değere indirgenir."

-- SQL Server version of the anchor
DATEADD(day, -1 * rn, login_date) AS grp

Neden Kendisiyle Birleştirme Kullanılmıyor

Mülakatçı, l1.login_date = l2.login_date + 1 gibi bir kendisiyle birleştirmeden neden kaçındığınızı sorabilir. Söyleyebileceğiniz nedenler şunlardır:

  • Kendisiyle birleştirme yalnızca ardışıklığı test eder, serinin tamamını değil — eksiksiz serileri oluşturmak için yine gruplama gerekir.
  • İyi dizinler olmadan satırları çoğaltabilir ve O(n²) maliyete ulaşabilir.
  • Satır numarası yöntemi, tek bir sıralı geçiş yapar ve çok daha iyi ölçeklenir.

Pencere işlevleri, bu problemlerde beklenen modern yanıttır.

Yinelenenlere Karşı Önlem Alma

Bu tekniğin tamamı, kullanıcı başına günde bir satır varsayımına dayanır. Kaynakta aynı gün için birden fazla giriş varsa, aynı tarihe ait iki satır farklı satır numaraları alır ve çıpayı bozar.

Önce tekilleştirerek önlem alın: zaman damgalarını tarihlere dönüştürüp DISTINCT kullanın veya eşit tarihler aynı numarayı paylaşsın diye tarih üzerinde DENSE_RANK kullanarak ROW_NUMBER yerine onu tercih edin.

WITH days AS (
  SELECT DISTINCT user_id, login_ts::date AS login_date
  FROM raw_logins
)
SELECT * FROM days;

Tam Çözüm

Tüm parçaları bir araya getirdiğinizde, her ardışık gün serisini başlangıcı, bitişi ve uzunluğuyla listeleyen, mülakata hazır temiz bir yanıt elde edersiniz.

Aynı iskelet — tekilleştir, numaralandır, çıkar, grupla — size yöneltilecek neredeyse her "ardışık" soruyu çözer.

WITH days AS (
  SELECT DISTINCT user_id, login_ts::date AS login_date
  FROM raw_logins
),
numbered AS (
  SELECT user_id, login_date,
    ROW_NUMBER() OVER (
      PARTITION BY user_id ORDER BY login_date
    ) AS rn
  FROM days
)
SELECT user_id,
  MIN(login_date) AS streak_start,
  MAX(login_date) AS streak_end,
  COUNT(*)        AS streak_len
FROM numbered
GROUP BY user_id, login_date - rn
ORDER BY user_id, streak_start;

Hızlı Kontrol

Temel fikri kavrayışınızı sınayın.

Özet

Ardışık günler için temel kalıbı öğrendiniz:

  • Tekilleştirin ve kullanıcı başına günde bir satır bırakın.
  • Tarihe göre sıralanmış ve kullanıcıya göre bölümlenmiş ROW_NUMBER kullanın.
  • Her seri için sabit bir çıpa elde etmek üzere satır numarasını tarihten çıkarın.
  • Çıpa üzerinde GROUP BY uygulayın ve başlangıç, bitiş ve uzunluk için toplulaştırın.

Bu boşluklar ve adalar iskeleti tek geçişte ölçeklenir ve kendisiyle birleştirmeleri geride bırakır. Sırada bunu kullanarak kullanıcı başına en uzun seriyi hesaplayacaksınız.

Sıkça Sorulan Sorular

“Ardışık Takvim Günlerini Tespit Etme” dersi ücretsiz mi?

Evet — “Ardışık Takvim Günlerini Tespit Etme” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve SQL Interview Prep kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. SQL Interview Prep kursu toplamda 4 dersten oluşur.

“Ardışık Takvim Günlerini Tespit Etme” dersinde ne öğreneceğim?

Kesintisiz gün dizilerini bulmak için tarih aritmetiğini ve satır numaralarını kullanın. SQL Interview Prep ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

SQL Interview Prep öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te SQL Interview Prep, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 1. dersidir.

“Ardışık Takvim Günlerini Tespit Etme” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu SQL Interview Prep dersinde kod yazıp çalıştırabilir miyim?

Evet. Her SQL Interview Prep dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Ardışık Takvim Günlerini Tespit Etme
  2. Kullanıcı Başına En Uzun Seri
  3. Koşulu Sağlayan N Ardışık Satır
  4. Bugün İtibarıyla Devam Eden Seri
← SQL Interview Prep Sayfasına Dön