CASE

Marcin, jeżeli chcesz popracować nad wartością zaciąganą z bazy, z określonej kolumny/pola to moja sugestia jest następująca: porzuć stosowanie „DECODE”.
Tobie i wszystkim polecam stosowanie „CASE”. Stosujemy ją w bloku pomiędzy „SELECT” a „FROM”.


Jeżeli dodatkowo używamy funkcji agregujących to trzeba całe wyrażenie „CASE…” skopiować do sekcji po „GROUP BY”. Marcin, kopiując wyrażenie „CASE…” do sekcji po”ORDER BY” pomiń alias jeżeli go nadałeś, no to co jest pomiędzy END a następnym przecinkiem (jeżeli jest).  Przypadek użycia „CASE” z grupowaniem jest pokazany na przykładzie 2.


Wybornie ww. wyrażenie nadaje się do modyfikowania, etykietowania wartości występujących w kolumnach, zamiany wartości z kolumny na inną, niekoniecznie tego samego typu.


Ja wiem Marcinie, iż wolisz przykłady, zatem ten z numerem 1 dotyczy następującej sytuacji:


  • tabela, którą przetwarzamy: pozyczki,
  • tabela jest codziennie zasilana aktualnym stanem, to jest występuje poje: data_stanu,
  • pole dni_opoznienia: zawiera liczbowo określoną liczbę o ile dni opóźnia się pożyczkobiorca w stosunku do terminu zapłaty najstarszej opóźnionej raty.
Dane w polu dni_opoznienia są co prawda dyskretne, ale muszą przyjmować wiele wartości. Często w analizach wystarczy, a nawet trzeba określić w jakim przedziale czasowym jest opóźnienie danej umowy.  Nadanie nowych etykiet dla wartości dni_opoznienia jest pokazane w przykładzie. 


Uwaga: kolego, kolejność warunków/klauzul „when …” jest istotna. 
W pierwszym kroku wszystkie wartości w polu dni_opoznienia zostaną sprawdzone czy nie są „0” i jeżeli tak, to otrzymają odpowiednią etykietę. W drugim kroku już nie są przeglądane wszystkie wartości (wszystkie wiersze tabeli) tylko te, które nie dostały etykiety w pierwszym kroku. Przeglądany zbiór w drugim kroku jest mniejszy (lub taki sam, jeżeli w pierwszym kroku nowa etykieta nie została nadana).


W drugim kroku umowa mająca „0” dni opóźnienia nie jest brana pod uwagę, bo już otrzymała etykietę nadaną w pierwszy kroku.
Umiejętne stosowanie kolejności może znacznie ułatwić, uprościć zapis.


Kolejna uwaga: „CASE” nie jest odporne na NULL, zatem brak zapisu w naszym przykładzie:
when dni_opoznienia is null then '6 brak danych'
powodowałby, iż przypadki, gdy zawartość pola dni_opoznienia byłaby NULL otrzymałyby etykietę ostatnią to jest określoną po „ELSE”.

Przykład 1:
SELECT
 numer_umowy
 , case
   when dni_opoznienia = 0 then '1 brak opóźnienia'
   when dni_opoznienia < 30 then '2 opóźnienie w przedziale <1 ; 30)'
   when dni_opoznienia < 90 then '3 opóźnienie w przedziale <30 ; 90)'  
   when dni_opoznienia < 180 then '4 opóźnienie w przedziale <90 ; 180)'
   when dni_opoznienia < 180 then '4 opóźnienie w przedziale <90 ; 180)'
   when dni_opoznienia is null then '6 brak danych'      
   else '5 opóźnienie 180 dni i więcej'
     end przedzial_opoznienia
FROM pozyczki
WHERE  data_stanu='20141231';

Przykład 2, jak kopiować „case” jeżeli grupuję;
SELECT
 data_stanu
 , case
   when dni_opoznienia = 0 then '1 brak opóźnienia'
   when dni_opoznienia < 30 then '2 opóźnienie w przedziale <1 ; 30)'
   when dni_opoznienia < 90 then '3 opóźnienie w przedziale <30 ; 90)'  
   when dni_opoznienia < 180 then '4 opóźnienie w przedziale <90 ; 180)'
   when dni_opoznienia < 180 then '4 opóźnienie w przedziale <90 ; 180)'
   when dni_opoznienia is null then '6 brak danych'      
   else '5 opóźnienie 180 dni i więcej'
     end przedzial_opoznienia
  , sum(kapital_do_splaty) –- funkcja agregująca
FROM pozyczki WHERE data_stanu>'20141231'
GROUP BY  
data_stanu
, case
   when dni_opoznienia = 0 then '1 brak opóźnienia'
   when dni_opoznienia < 30 then '2 opóźnienie w przedziale <1 ; 30)'
   when dni_opoznienia < 90 then '3 opóźnienie w przedziale <30 ; 90)'  
   when dni_opoznienia < 180 then '4 opóźnienie w przedziale <90 ; 180)'
   when dni_opoznienia < 180 then '4 opóźnienie w przedziale <90 ; 180)'
   when dni_opoznienia is null then '6 brak danych'      
   else '5 opóźnienie 180 dni i więcej'
     end ; -- skopiowałem całą treść klauzuli, ale bez aliasu



Brak komentarzy:

Prześlij komentarz