Archiwa tagu: case

SQL IN z CASE

SQL IN z CASE



DEFINICJA

Polecenie IN opisywałem tutaj, ale ostatnio „buszując” w Internecie natrafiłem na ciekawe pytanie dotyczące zapytania SQL i postanowiłem rozwinąć trochę poprzedni wpis o rozwiązanie z CASE i podzapytaniem.


Przykład zastosowania polecenia IN z CASE

SELECT
*
FROM
nazwa_tabeli
WHERE
nazwa_pola IN (
CASE
WHEN warunek1 THEN wartość1
WHEN warunek2 THEN wartość2
ELSE warunek3 THEN wartość3
END
)

Widzimy tutaj że w zależności od wyniku polecenie CASE zostanie wybrana wartość która będzie argumentem dla polenia IN.


Przykład zastosowania polecenia IN z podzapytaniem

SELECT
*
FROM
nazwa_tabeli
WHERE
nazwa_pola IN (
SELECT TOP 1
nazwa_pola
FROM
nazwa_tabeli
WHERE
warunek
)

W tym przypadku zbiorem wartości dla IN jest wynik podzapytania.
Można by pójść o krok dalej i uzależnić wartości dla zbioru IN od zmiennej.


Przykład zastosowania polecenia IN z CASE i z deklaracją zmiennej.

DECLARE @zmienna varchar(5) = ‚100’

SELECT
*
FROM
nazwa_tabeli
WHERE
nazwa_pola IN (
CASE
WHEN @zmienna < 100 THEN wartość1
WHEN @zmienna = 100 THEN wartość2
WHEN @zmienna > 100 THEN wartość3
END
)


Przykład zastosowania polecenia IN z podzapytaniem i z deklaracją zmiennej.

DECLARE @zmienna varchar(5) = ‚100’

SELECT
*
FROM
nazwa_tabeli
WHERE
nazwa_pola IN (
SELECT TOP 1
nazwa_pola
FROM
nazwa_tabeli
WHERE
nazwa_pola <= @zmienna
)


SQL CASE

SQL CASE



DEFINICJA

Funkcje CASE służy do zastępowania, w wynikach zapytania, wartości „oryginalnych” w kolumnach innymi wartościami w zależonści od zdefiniowanych przez nas warunków.

SQL CASE składnia

CASE
WHEN warunek1 THEN nowa_wartość_dla_rekodów_spełniająych_ten_warunek
WHEN warunek2 THEN nowa_wartość_dla_rekodów_spełniająych_ten_warunek
WHEN warunek3 THEN nowa_wartość_dla_rekodów_spełniająych_ten_warunek
ELSE nowa_wartość_dla_rekodów_nie_spełniająych_powyższych_warunków
END 


Przykład zastosowania CASE (baza Adventureworks)

Wyświetl wszystkie osoby z bazy wraz z „rodzajem powiązania” z firmą. Wyświetl pełną nazwę typu osoby.

SELECT
LastName
,Firstname
,CASE
 WHEN PersonType = ‚EM’ THEN ‚Employee’
WHEN PersonType = ‚SC’ THEN ‚Store Contact’
WHEN PersonType = ‚IN’ THEN ‚Individual (retail) customer’
WHEN PersonType = ‚SP’ THEN ‚Sales person’
WHEN PersonType = ‚VC’ THEN ‚Vendor contact’
WHEN PersonType = ‚GC’ THEN ‚General contact’
 ELSE ‚b.d.’
END AS [Typ osoby]
FROM 
Person.Person

 


 Przykład zastosowania CASE (baza Northwind)

Wyświetl tytuly grzecznościowe pracowników i zamień je na polskie nazwy.

SELECT
LastName AS Nazwisko
,FirstName AS Imię
,CASE
WHEN TitleOfCourtesy = ‚Mr.’ THEN ‚Pan’
WHEN TitleOfCourtesy = ‚Mrs.’ THEN ‚Pani’
WHEN TitleOfCourtesy = ‚Ms.’ THEN ‚Panna’
WHEN TitleOfCourtesy = ‚Dr.’ THEN ‚Doktor’
ELSE ‚b.d.’
END AS TytułGrzecznościowy
FROM 
Employees


Odejmowanie dwóch dat (obecna – data zdarzenia) i prezentacja wyników w dniach

PROBLEM:

Odejmowanie dwóch dat (obecna – data zdarzenia) i prezentacja wyników w dniach

SZCZEGÓŁY:

Chciałbym odjąć dwie daty, obecną – data zdarzenia (np. data zapisania rekordu do bazy), w celu prezentacji wyników odejmowania w dniach. Jeśli zdarzenie (np. data zapisania rekordu do bazy) mała miejsce dzisiaj to w wyniku zapytania chcę otrzymać tekst „dzisiaj” i analogicznie jeśli zdarzenie miało miejsce wczoraj to chcę otrzymać tekst ‚wczoraj’ i tak samo z ‚przedwczoraj’. Jeśli zdarzenie miało miejsce później niż przedwczoraj to wynikiem odejmowania ma być prezentacja daty zdarzenia w formacie „Y-m-d”, czyli Rok-miesiąc-dzień.

ROZWIĄZANIE:

Możemy ten problem rozwiązać na poziomie aplikacji czy strony WWW, pobrać datę z bazy i porównać ją daty obecnej. Pewniejszym rozwiązaniem będzie uzyskanie potrzebnego wyniku od razy z zapytania SQL. W tym celu możemy skorzystać z funkcji DATEDIFF, która zwróci nam różnicę między parametrami (w tym przypadku datami). Aby uzyskać zadowalający nas efekt musimy jeszcze skorzystać z funkcji CASE która w zależności od wyniku odejmowania dat zwróci nam wartość o którą nam chodzi (‚dzisiaj’, ‚wczoraj’, ‚przedwczoraj’ lub datę zapisu rekordu do bazy inną nić wymienione).

SELECT
id
,tytul
,opis
,cena
,case(datediff(now(),data_dodania))               <- tutaj następuje odjęcie dat

WHEN 0 THEN ‚dzisiaj’      <- jeśli zdarzenie miało miejsce dzisiaj to różnicą w odejmowaniu jest 0, wtedy chcemy wyświetlić tekst  ‚dzisiaj’

WHEN 1 THEN ‚wczoraj’  <- jeśli zdarzenie miało miejsce wczoraj to różnicą w odejmowaniu jest 1, wtedy chcemy wyświetlić tekst  ‚wczoraj’

WHEN 2 THEN ‚przedwczoraj’   <- analogicznie jak wyżej

ELSE date(data_dodania) END as data_dodania   <- wszystkie inne przypadki to sytuacje kiedy zdarzenie miało miejsce wcześniej niż przedwczoraj i wtedy chcemy wyświetlić konkretną datę w formacie „Y-m-d”
,data_dodania as data_dodania_org   <- jeśli oryginalna data jest w formacie DATETIME to możemy ją wykorzystać do sortowania
FROM
tab1
WHERE
[..TUTAJ PODAJEMY WARUNKI WYSZUKIWANIA REKORDÓW…]
ORDER BY
data_dodania_org DESC   <- jak już wcześniej pisałem możemy wykorzystać oryginalną datę do sortowania

GOTOWE 🙂 MIŁEJ ZABAWY