0Pricing
Coding Interview Prep · Ders

Tarih ve Durum Değişiklikleriyle Adalar

Yaygın bir abonelik durumu sorusu olan, aynı durumdaki ardışık dönemleri gruplayın.

Tarih ve Durum Değişiklikleriyle Adalar, CoddyKit'te ücretsiz bir Coding Interview Prep dersidir. Bu, 4 dersinin 4. 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, Coding Interview Prep öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Coding Interview Prep kursu toplamda 4 dersten oluşur.

Değişen Değerlere Göre Tanımlanan Adalar

Boşluklar ve adalar probleminin iş açısından en anlamlı çeşidi, aynı durumu paylaşan ardışık satırları gruplayarak gürültülü bir olay günlüğünü temiz durum dönemlerine dönüştürür. Klasik soru şöyledir: “Bir abonelik olay günlüğü verildiğinde, kullanıcının her durumda kaldığı kesintisiz dönem için bir satır döndürün.”

Burada komşuluk, “değerlerin 1 kadar farklı olması” anlamına gelmez. Durumun önceki satırdan değişmemiş olması anlamına gelir. Durum değiştiği anda yeni bir ada başlar. Salt satır numarası yöntemine kıyasla LAG tabanlı tekniğin öne çıktığı yer burasıdır.

Abonelik Örneği

Tarihe göre sıralanmış, tek bir kullanıcıya ait bir sub_events tablosunu ele alın:

  • 2026-01-01 etkin
  • 2026-02-01 etkin
  • 2026-03-01 duraklatıldı
  • 2026-04-01 etkin
  • 2026-05-01 etkin

İstenen çıktı üç durum dönemidir: Oca-Şub etkin, Mar duraklatıldı, Nis-May etkin. İki etkin döneminin ayrı adalar olduğuna dikkat edin; çünkü aralarına duraklatılmış bir dönem girer. Durum aynı olsa bile ardışık değilse farklı adalar söz konusudur.

CREATE TABLE sub_events (
  user_id INT, status TEXT, event_date DATE
);
INSERT INTO sub_events VALUES
 (1,'active','2026-01-01'),(1,'active','2026-02-01'),
 (1,'paused','2026-03-01'),(1,'active','2026-04-01'),
 (1,'active','2026-05-01');

Durumun Değiştiği Yerleri İşaretleme

Her satırın durumunu bir önceki satırın durumuyla karşılaştırmak için LAG kullanın. Değerler farklı olduğunda (veya ilk satır için önceki değer NULL olduğunda) yeni bir ada başlar. Değişiklik için 1, diğer durumlarda 0 üretin.

Kullanıcı içindeki satırları kesin olarak tarihe göre sıralayın. Verilerimizde değişiklik işaretleri 1,0,1,1,0 olur ve üç dönem sınırını gösterir.

SELECT
  user_id, status, event_date,
  CASE
    WHEN status = LAG(status)
      OVER (PARTITION BY user_id ORDER BY event_date)
    THEN 0 ELSE 1
  END AS is_change
FROM sub_events;

Birikimli Toplamı Dönem Anahtarına Dönüştürme

Önceki yöntemde olduğu gibi, değişiklik işaretlerinin birikimli toplamı her durum dönemi içinde sabit kalan bir grup anahtarı üretir: satırlarımız için 1,1,2,3,3. Her farklı anahtar bir kesintisiz dönemdir.

Satır numarası farkı yöntemi burada işe yaramaz; çünkü durum, 1'er ilerleyen bir sayı değildir. Komşuluk “değişmemiş değer” anlamına geldiğinde doğru araç LAG ve birikimli toplam yöntemidir.

WITH flagged AS (
  SELECT user_id, status, event_date,
    CASE WHEN status = LAG(status)
           OVER (PARTITION BY user_id ORDER BY event_date)
         THEN 0 ELSE 1 END AS is_change
  FROM sub_events
)
SELECT user_id, status, event_date,
  SUM(is_change)
    OVER (PARTITION BY user_id ORDER BY event_date) AS grp
FROM flagged;

Durum Dönemlerini Birleştirme

Şimdi her dönemin aralığını raporlamak için user_id, status ve birikimli toplam anahtarı ile GROUP BY uygulayın. Durum bir dönem içinde sabit olduğundan, durumu GROUP BY ifadesine eklemek güvenlidir; ayrıca durumu bir toplama işlevi kullanmadan seçmenizi sağlar.

Sonuç tam olarak üç satırdır: etkin 01-01 ile 02-01 arası, duraklatıldı 03-01 ile 03-01 arası, etkin 04-01 ile 05-01 arası.

WITH flagged AS (
  SELECT user_id, status, event_date,
    CASE WHEN status = LAG(status)
           OVER (PARTITION BY user_id ORDER BY event_date)
         THEN 0 ELSE 1 END AS chg
  FROM sub_events
),
keyed AS (
  SELECT user_id, status, event_date,
    SUM(chg) OVER (PARTITION BY user_id ORDER BY event_date) AS grp
  FROM flagged
)
SELECT user_id, status,
  MIN(event_date) AS period_start,
  MAX(event_date) AS period_end
FROM keyed
GROUP BY user_id, status, grp
ORDER BY user_id, period_start;

Olaylardan Yarı Açık Aralıklara

İnce bir mülakat noktası: bir olay tarihi, bir durumun başladığı zamanı belirtir ve dönem, aynı durumdaki son olay tarihinde değil, bir sonraki durum başladığında gerçekten sona erer. Doğru dönem sonu çoğu zaman bir sonraki dönemin başlangıcıdır; bu, [başlangıç, sonraki başlangıç) yarı açık aralığıyla modellenir.

LEAD kullanarak, daraltılmış dönemler üzerinden bir sonraki dönemin başlangıcını hesaplayın ve son dönemi açık uçlu bırakın (NULL veya 'mevcut').

WITH periods AS (
  -- output of the previous collapse step
  SELECT user_id, status, period_start FROM collapsed
)
SELECT user_id, status, period_start,
  LEAD(period_start)
    OVER (PARTITION BY user_id ORDER BY period_start)
    AS period_end_exclusive
FROM periods;

Arka Arkaya Tekrarlanan Durumları Ele Alma

Günlükte aralarında hiçbir değişiklik olmayan etkin, etkin, etkin gibi gereksiz satırlar varsa ne olur? Tekrarlanan satırlarda değişiklik bayrağı 0 olur; bu nedenle kümülatif toplam onları otomatik olarak aynı ada içinde tutar. İstenen davranış budur: arka arkaya gelen özdeş durumlar tek bir dönemde birleştirilir.

Tekrarların bu doğal tekilleştirilmesi, değişiklik bayrağı yönteminin önemli bir avantajıdır ve bunu mülakatçıya özellikle belirtmekte fayda vardır.

Zamandaki Boşluklar Bir Dönemi Ne Zaman Bölmeli

Bazen "aynı durum" yeterli değildir; durum aynı olsa bile büyük bir zaman boşluğu dönemi bölmelidir. Örneğin, ocak ayında etkin olan bir kullanıcının altı aylık bir sessizlikten sonra yeniden etkin olması iki dönem sayılabilir.

Değişiklik bayrağını ikinci bir koşulla genişletin: durum değiştiğinde veya önceki olaydan bu yana geçen süre bir eşiği aştığında yeni bir ada başlatın. Böylece her iki ardışıklık kuralını düzgün biçimde bir araya getirebilirsiniz.

CASE
  WHEN status = LAG(status)
         OVER (PARTITION BY user_id ORDER BY event_date)
   AND event_date - LAG(event_date)
         OVER (PARTITION BY user_id ORDER BY event_date) <= 31
  THEN 0 ELSE 1
END AS is_change

Farklı Durum Geçişlerini Sayma

Doğal bir devam sorusu şudur: "Bu kullanıcı kaç kez durum değiştirdi?" Bunun yanıtı, değişiklik bayraklarının sayısından ilk bayrağı çıkarmaktır; çünkü ilk bayrak bir geçişi değil, başlangıç durumunu belirtir.

Eşdeğer olarak bu, dönem sayısının 1 eksiğidir. Kümülatif toplam anahtarı bu bilgiyi zaten kodlar; dolayısıyla yanıt, dönemler için oluşturduğunuz aynı yapıdan elde edilir.

WITH flagged AS (
  SELECT user_id,
    CASE WHEN status = LAG(status)
           OVER (PARTITION BY user_id ORDER BY event_date)
         THEN 0 ELSE 1 END AS chg
  FROM sub_events
)
SELECT user_id, SUM(chg) - 1 AS status_switches
FROM flagged GROUP BY user_id;

Burada Kendisiyle Birleştirme Neden İşe Yaramaz

Durum dönemleri için kendisiyle birleştirme kullanan bir çözümün her satırı komşusuyla eşleştirmesi, değişiklikleri algılaması ve ardından sınırları bir araya getirmesi gerekir. Bu, hataya açık, çok adımlı ve üç veya daha fazla dönem söz konusu olduğunda zorlanan zahmetli bir süreçtir.

LAG-bayrak-kümülatif toplam-gruplama işlem hattı, birleştirme kullanmadan tek geçişte her sayıda dönemi ele alır. Doğrusal tek geçiş ile karesel kendisiyle birleştirmeyi karşılaştırmak, kıdemli düzeyde akıl yürütme becerisi olarak mülakatçıların tam da ödüllendirdiği noktadır.

Yeniden Kullanılabilir Bir Şablon

Bu dört maddeli şablonu ezberleyin; yalnızca CASE içindeki ardışıklık testini değiştirerek durum adası ailesinin tamamını çözer:

  1. bayrak: Yeni bir ada algılamak için LAG içeren CASE.
  2. anahtar: Bölümlenmiş ve sıralanmış bayrağın kümülatif SUM değeri.
  3. birleştirme: Bölüm sütununa, duruma ve anahtara göre GROUP BY uygulama.
  4. aralık (isteğe bağlı): Yarı açık dönem sonları için LEAD.

Aynı iskelet ardışık tam sayıları, tarihleri ve durumları işler; yalnızca CASE koşulu değişir.

Hızlı Kontrol

Durum adası gruplama kuralını kavradığınızı doğrulayın.

Özet: Durum ve Tarih Adaları

Artık boşluklar ve adalar problemlerinin en kapsamlı çeşidini çözebilirsiniz:

  • Ardışıklık = önceki satırdaki durum değişmemiştir; bayrak değişikliklerini LAG ile algılayın.
  • Değişiklik bayraklarının kümülatif toplamını alarak dönem başına bir grup anahtarı oluşturun.
  • Dönem aralıklarını elde etmek için GROUP BY user_id, status, key ile birleştirin.
  • Yarı açık aralıkların sonları için LEAD kullanın; büyük zaman boşluklarında bölmek için bayrağı genişletin.
  • Tekrarlanan özdeş satırlar otomatik olarak birleştirilir; geçiş sayıları da aynı bayraklardan elde edilir.
  • Yeniden kullanılabilir tek bir şablon tam sayıları, tarihleri ve durumları kapsar; yalnızca CASE değişir.

Böylece boşluklar ve adalar dersi tamamlanır; bu konu, SQL mülakatlarında güvenilir bir kıdemli düzey göstergesidir.

Sıkça Sorulan Sorular

“Tarih ve Durum Değişiklikleriyle Adalar” dersi ücretsiz mi?

Evet — “Tarih ve Durum Değişiklikleriyle Adalar” 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 Coding Interview Prep kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Coding Interview Prep kursu toplamda 4 dersten oluşur.

“Tarih ve Durum Değişiklikleriyle Adalar” dersinde ne öğreneceğim?

Yaygın bir abonelik durumu sorusu olan, aynı durumdaki ardışık dönemleri gruplayın. Coding 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.

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

Önceden deneyim gerekmez. CoddyKit'te Coding 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 4. dersidir.

“Tarih ve Durum Değişiklikleriyle Adalar” 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 Coding Interview Prep dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Coding 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. Boşluklar ve Adalar Problemini Tanıma
  2. Satır Numarası Farkı Hilesi
  3. Bir Dizideki Boşlukları Bulma
  4. Tarih ve Durum Değişiklikleriyle Adalar
← Coding Interview Prep Sayfasına Dön