Professional Documents
Culture Documents
Funkcje Wbudowane - Teoria
Funkcje Wbudowane - Teoria
Funkcje wbudowane
T-SQL oferuje mnóstwo wbudowanych funkcji, które u atwiaj prac z danymi.
W tym rozdziale omówimy funkcje skalarne, to znaczy takie funkcje, które jako pa-
rametry przyjmuj pojedyncze warto ci i wynikiem dzia ania których równie jest
pojedyncza warto .
wiczenia
wiczenia b d wykonywane na tej samej tabeli Employee, co wiczenia z rozdzia u 1.
wiczenie 2.1
Dla ka dego pracownika wy wietl imi , nazwisko oraz rok jego urodzenia.
Oczekiwany wynik
Rysunek 2.1.
Oczekiwany wynik
wiczenia 2.1
62 SQL. Jak osi gn mistrzostwo w konstruowaniu zapyta
Rozwi zanie
W T-SQL istnieje funkcja YEAR, która dla podanej daty zwraca rok.
Aby wi c wy wietli rok urodzenia pracownika, musimy u y funkcji YEAR, której ar-
gumentem b dzie data urodzenia:
SELECT FirstName, LastName, YEAR(BirthDate) as 'Rok urodzenia'
FROM Employee
wiczenie 2.2
Dla ka dego pracownika wy wietl imi , nazwisko oraz rok, miesi c i dzie jego uro-
dzenia oraz dzie tygodnia, w jakim si urodzi .
Oczekiwany wynik
Rysunek 2.2.
Oczekiwany wynik
wiczenia 2.2
Rozwi zanie
Obok funkcji YEAR, zwracaj cej rok z podanej daty, istniej równie funkcje:
MONTH zwracaj ca miesi c z podanej daty,
DAY zwracaj ca dzie z podanej daty,
DATEPART zwracaj ca wybrany sk adnik daty, w zale no ci od pierwszego
parametru funkcji. Ten parametr mo e mie nast puj ce warto ci:
year zwraca rok, np. DATEPART(year, '2000-12-15') zwróci warto 2000;
month zwraca miesi c, np. DATEPART(year, '2000-12-15') zwróci warto 12;
day zwraca dzie , np. DATEPART(year, '2000-12-15') zwróci warto 15.
Rozdzia 2. Funkcje wbudowane 63
lub:
SELECT
FirstName,
LastName,
DATEPART(year, BirthDate) as 'Rok urodzenia',
DATEPART(month, BirthDate) as 'Miesi c',
DATEPART(day, BirthDate) as 'Dzie ',
DATENAME(weekday, BirthDate) as 'Dzie tygodnia'
FROM Employee
wiczenie 2.3
Wy wietl wszystkich pracowników urodzonych w 1990 roku.
Oczekiwany wynik
64 SQL. Jak osi gn mistrzostwo w konstruowaniu zapyta
Rozwi zanie
Warunek urodzony w 1990 roku oznacza urodzony w dzie lub po dniu 1 stycznia
1990 roku oraz urodzony przed 1 stycznia 1991 roku.
Zapytanie mo e wi c wygl da nast puj co:
SELECT *
FROM Employee
WHERE BirthDate >= '1990-1-1'
AND BirthDate < '1991-1-1'
wiczenie 2.4
Wy wietl wszystkich pracowników urodzonych w maju 1990 roku.
Oczekiwany wynik
Rozwi zanie
Aby zbudowa to zapytanie, mo emy znowu u y pe nych dat, czyli urodzony w maju
1990 roku oznacza urodzony w dzie lub po dniu 1 maja 1990 roku oraz urodzony
przed 1 czerwca 1990 roku.
Mo emy równie u y znanych ju funkcji YEAR oraz MONTH, które zwracaj odpo-
wiednio rok i miesi c z podanej daty:
SELECT *
FROM Employee
WHERE YEAR(BirthDate) = 1990
AND MONTH(BirthDate) = 5
Rozdzia 2. Funkcje wbudowane 65
wiczenie 2.5
Wy wietl bie c dat i godzin .
Oczekiwany wynik
Wynik b dzie oczywi cie zale a od bie cej daty poni ej wynik dla 24 maja 2015:
Rysunek 2.5.
Oczekiwany wynik
wiczenia 2.5
Rozwi zanie
Istnieje funkcja systemowa, której zwracan warto ci jest w a nie bie ca data i godzina:
SELECT GETDATE()
Pami tamy równie o dobrej praktyce nazywania kolumn, które s wynikiem funkcji
i nie posiadaj w asnej nazwy:
SELECT GETDATE() as 'Teraz'
wiczenie 2.6
Wy wietl, ile lat min o od daty 1 stycznia 1990 roku.
Oczekiwany wynik
Wynik b dzie oczywi cie zale a od bie cej daty poni ej wynik dla roku 2015:
Rysunek 2.6.
Oczekiwany wynik
wiczenia 2.6
Rozwi zanie
Istnieje funkcja systemowa DATEDIFF, która oblicza, ile czasu min o pomi dzy dwiema
podanymi datami.
Obliczany przedzia czasu zale y od sk adnika czasu (ang. datepart), który nale y poda
jako parametr funkcji:
year liczy liczb lat,
month liczy liczb miesi cy,
day liczy liczb dni,
hour liczy liczb godzin,
66 SQL. Jak osi gn mistrzostwo w konstruowaniu zapyta
Przyk adowo, je li chcieliby my policzy , ile dni min o mi dzy dat 1.01.2015 a dat
20.01.2015, napiszemy:
DATEDIFF(day, '2015-01-01', '2015-01-20')
Aby policzy , ile lat min o od daty 1 stycznia 1990 roku do dnia dzisiejszego, napiszemy
nast puj ce zapytanie:
SELECT DATEDIFF(year, '1990-01-01', GETDATE()) as IleLat
wiczenie 2.7
Dla ka dego pracownika wy wietl jego imi , nazwisko oraz wiek.
Oczekiwany wynik
Rysunek 2.7.
Oczekiwany wynik
wiczenia 2.7
Rozwi zanie
Wiek danego pracownika jest to liczba lat, która min a od dnia jego narodzin (t dat
przechowujemy w kolumnie BirthDate) do dnia dzisiejszego.
Rozdzia 2. Funkcje wbudowane 67
wiczenie 2.8
Wy wietl wszystkich pracowników, którzy maj wi cej ni 25 lat.
Oczekiwany wynik
Rozwi zanie
Wszystkich funkcji, a wi c równie tej przedstawionej w powy szych wiczeniach
funkcji DATEDIFF, mo na u ywa równie w sekcji WHERE zapytania.
wiczenie 2.9
Wy wietl dane wszystkich pracowników, którzy maj mniej ni 30 lat i zarabiaj mniej
ni 2000 z .
Oczekiwany wynik
68 SQL. Jak osi gn mistrzostwo w konstruowaniu zapyta
Rozwi zanie
Do znalezienia danych pracowników, którzy maj mniej ni 30 lat, u yjemy funkcji
DATEDIFF.
Poniewa chcemy znale dane pracowników, którzy spe niaj obydwa warunki (wiek
mniej ni 30 lat i zarobki ni sze ni 2000 z ), warunki po czymy przy u yciu s owa AND.
wiczenie 2.10
Dla ka dego aktywnego pracownika wy wietl imi , nazwisko oraz informacj , ile lat
ju pracuje w tej firmie.
Oczekiwany wynik
Rysunek 2.10.
Oczekiwany wynik
wiczenia 2.10
Rozwi zanie
Aby wyliczy liczb przepracowanych lat, u yjemy funkcji DATEDIFF, która policzy,
ile lat min o od daty zatrudnienia (kolumna HireDate) do dnia dzisiejszego:
DATEDIFF(yy, HireDate, GETDATE())
Poniewa chcemy wy wietli te dane tylko dla aktywnych pracowników, musimy doda
warunek:
Active = 1
Rozdzia 2. Funkcje wbudowane 69
wiczenie 2.11
Dla ka dego aktywnego pracownika wy wietl imi , nazwisko oraz informacj , ile
miesi cy ju pracuje w tej firmie.
Oczekiwany wynik
Rysunek 2.11.
Oczekiwany wynik
wiczenia 2.11
Rozwi zanie
Aby wyliczy liczb przepracowanych miesi cy, podobnie jak w poprzednim wiczeniu,
u yjemy funkcji DATEDIFF, ale tym razem jako sk adnik daty b d cy parametrem tej
funkcji podamy mm:
DATEDIFF(mm, HireDate, GETDATE())
wiczenie 2.12
Wy wietl dane wszystkich pracowników, którzy przepracowali w tej firmie co naj-
mniej 10 miesi cy, ale nie wi cej ni 20.
Oczekiwany wynik
70 SQL. Jak osi gn mistrzostwo w konstruowaniu zapyta
Rozwi zanie
Liczb przepracowanych miesi cy liczymy dok adnie tak, jak w poprzednim wiczeniu:
DATEDIFF(mm, HireDate, GETDATE())
Dodatkowo powinni pracowa nie wi cej ni 20 miesi cy, wi c liczba miesi cy, która
min a od dnia zatrudnienia do dnia dzisiejszego, powinna by mniejsza lub równa 20.
wiczenie 2.13
Dla ka dego pracownika wy wietl imi , nazwisko, rok urodzenia, rok, w którym zosta
zatrudniony, oraz liczb lat, któr mia w momencie zatrudnienia.
Oczekiwany wynik
Rysunek 2.13.
Oczekiwany wynik
wiczenia 2.13
Rozdzia 2. Funkcje wbudowane 71
Rozwi zanie
Do tej pory u ywali my funkcji DATEDIFF do obliczenia tego, jaki czas min do dnia
dzisiejszego. Równie dobrze mo na jej u y , aby policzy ró nic czasu pomi dzy
dwiema datami przechowywanymi w kolumnach, jak np. data urodzenia i data za-
trudnienia. W ten sposób policzymy, ile lat mia pracownik w momencie zatrudnienia:
DATEDIFF(year, BirthDate, HireDate)
wiczenie 2.14
Sprawd , czy istniej pracownicy, którzy przez pomy k maj wpisan dat zatrud-
nienia pó niejsz ni dat zwolnienia.
Oczekiwany wynik
Nie ma takiego pracownika, wi c powinni my otrzyma pusty wynik.
Rozwi zanie
Aby znale pomy kowe wpisy, wy wietlimy pracowników, których data zatrudnienia
jest wi ksza ni data zwolnienia (kolumna RelieveDate). U yjemy do tego po prostu
operatora porównania >.
wiczenie 2.15
Dla ka dego by ego pracownika, który nie pracuje ju w firmie, wy wietl imi i na-
zwisko oraz liczb miesi cy, któr przepracowa w firmie.
72 SQL. Jak osi gn mistrzostwo w konstruowaniu zapyta
Oczekiwany wynik
Rysunek 2.14.
Oczekiwany wynik
wiczenia 2.15
Rozwi zanie
Ka dy pracownik ma ustawiony znacznik Active, który przyjmuje warto ci 1 (prawda)
i 0 (fa sz) oznaczaj cy, czy pracownik wci pracuje w danej firmie. By y pra-
cownik taki, który ju nie pracuje ma ustawiony znacznik Active na 0 (fa sz).
Aby policzy liczb miesi cy, które pracownik przepracowa , policzymy ró nic po-
mi dzy dat zatrudnienia i dat zwolnienia, u ywaj c funkcji DATEDIFF i znacznika
czasu month:
DATEDIFF(MM, HireDate, RelieveDate)
wiczenie 2.16
Dla ka dego pracownika wy wietl imi , nazwisko oraz inicja y.
Oczekiwany wynik
Rysunek 2.15.
Oczekiwany wynik
wiczenia 2.16
Rozdzia 2. Funkcje wbudowane 73
Rozwi zanie
Funkcja SUBSTRING zwraca podci g danego ci gu (czyli a cuch znaków zawarty w tym
ci gu).
Jako argumenty przyjmuje:
ci g, którego cz chcemy zwróci ,
liczb oznaczaj c pocz tkowy znak, od którego ma si zaczyna podci g,
liczb znaków podci gu.
Aby znale inicja imienia, u yjemy funkcji SUBSTRING, która wy wietla pierwsz li-
ter z kolumny FirstName. Wy wietla ona pierwsz liter , czyli podci g o d ugo ci 1,
zaczynaj c od pozycji pierwszej. Analogicznie dzieje si przy zastosowaniu funkcji
LastName dla nazwiska.
Zapytanie b dzie mia o nast puj c posta :
SELECT
FirstName as 'Imi ',
LastName as 'Nazwisko',
SUBSTRING(FirstName, 1, 1) as 'Pierwsza litera imienia',
SUBSTRING(LastName, 1, 1) as 'Pierwsza litera nazwiska'
FROM Employee
wiczenie 2.17
Dla ka dego pracownika wy wietl nazwisko oraz liczb liter w nazwisku.
Oczekiwany wynik
Rysunek 2.16.
Oczekiwany wynik
wiczenia 2.17
74 SQL. Jak osi gn mistrzostwo w konstruowaniu zapyta
Rozwi zanie
Funkcja LEN zwraca d ugo danego ci gu znaków. Jako argument przyjmuje ci g
znaków, którego d ugo chcemy obliczy .
Do obliczenia liczby liter w nazwisku u yjemy funkcji LEN dla kolumny LastName:
SELECT
LastName as 'Nazwisko',
LEN(LastName) as 'Liczba liter w nazwisku'
FROM Employee
wiczenie 2.18
Wy wietl wszystkich pracowników, których nazwisko jest d u sze ni 6 liter.
Oczekiwany wynik
Rozwi zanie
Do znalezienia pracowników, których nazwisko jest d u sze ni 6 liter, u yjemy
funkcji LEN.
Jak to by o pokazane w poprzednich przyk adach, funkcji mo emy u ywa tak e pod-
czas definiowania warunków zapytania w sekcji WHERE.
Rozdzia 2. Funkcje wbudowane 75
wiczenie 2.19
Dla ka dego pracownika wy wietl jego imi , ale pisane ma ymi literami, oraz nazwisko
pisane wielkimi literami.
Oczekiwany wynik
Rysunek 2.18.
Oczekiwany wynik
wiczenia 2.19
Rozwi zanie
Istniej dwie funkcje zmieniaj ce wielko liter w wy wietlanym ci gu:
UPPER zmienia wszystkie litery w ci gu na wielkie, jako argument przyjmuje
ci g znaków,
LOWER zmienia wszystkie litery w ci gu na ma e, jako argument przyjmuje
ci g znaków.
Do wy wietlenia imienia przy zastosowaniu ma ych liter u yjemy funkcji LOWER i ko-
lumny FirstName, do wy wietlenia nazwiska przy zastosowaniu wielkich u yjemy
funkcji UPPER i kolumny LastName:
SELECT
LOWER(FirstName) as 'Imi ',
UPPER(LastName) as 'Nazwisko'
FROM Employee
76 SQL. Jak osi gn mistrzostwo w konstruowaniu zapyta
wiczenie 2.20
Dla ka dego pracownika wy wietl jego login. Login jest zbudowany z pierwszej litery
imienia i ca ego nazwiska.
Oczekiwany wynik
Rysunek 2.19.
Oczekiwany wynik
wiczenia 2.20
Rozwi zanie
Do wy wietlenia pierwszej litery imienia u yjemy funkcji SUBSTRING, która wy wietli
z kolumny FirstName ci g znaków od pierwszej litery o d ugo ci 1 (jednego) znaku:
SUBSTRING(FirstName, 1, 1)
wiczenie 2.21
Dla ka dego aktywnego pracownika wy wietl jego login napisany ma ymi literami.
Login, jak poprzednio, jest zbudowany z pierwszej litery imienia i ca ego nazwiska.
Oczekiwany wynik
Rysunek 2.20.
Oczekiwany wynik
wiczenia 2.21
Rozdzia 2. Funkcje wbudowane 77
Rozwi zanie
Login pracownika wy wietlimy dok adnie tak samo, jak w poprzednim wiczeniu:
SUBSTRING(FirstName, 1, 1) + LastName
Funkcje mog by zagnie d one, tzn. argumentem funkcji mo e by wynik dzia ania
innej funkcji. Na przyk ad argumentem funkcji LOWER mo e by ci g znaków, który
jest wynikiem dzia ania funkcji SUBSTRING, jak to przedstawiono poni ej:
LOWER(SUBSTRING(FirstName, 1, 1))
Poniewa chcemy mie pewno , e równie nazwisko jest wy wietlone ma ymi literami,
jako argument funkcji LOWER przekazujemy pe ny zbudowany login, czyli po czenie
pierwszej litery imienia z ca ym nazwiskiem:
LOWER(SUBSTRING(FirstName, 1, 1) + LastName)
Do zapytania do czymy jeszcze warunek, aby login by wy wietlany tylko dla ak-
tywnych pracowników. Zapytanie b dzie wygl da o nast puj co:
SELECT LOWER(SUBSTRING(FirstName, 1, 1) + LastName) as 'Login'
FROM Employee
WHERE Active = 1
wiczenie 2.22
Dla ka dego pracownika wy wietl krótki login, który jest zbudowany z pierwszej litery
imienia oraz pi ciu pierwszych liter nazwiska. Login ten wy wietl przy u yciu wielkich
liter. Przyk adowo, dla pracownika John Williams krótki login to JWILLI.
Oczekiwany wynik
Rysunek 2.21.
Oczekiwany wynik
wiczenia 2.22
Rozwi zanie
Do wy wietlenia pierwszej litery imienia u yjemy funkcji SUBSTRING, która wy wietli
z kolumny FirstName ci g od pierwszej litery o d ugo ci 1 znaku:
SUBSTRING(FirstName, 1, 1)
78 SQL. Jak osi gn mistrzostwo w konstruowaniu zapyta
Dodatkowo, poniewa chcemy wy wietli login przy u yciu wielkich liter, ca y login
b dzie argumentem funkcji UPPER:
SELECT
UPPER(SUBSTRING(FirstName, 1, 1) + SUBSTRING(LastName, 1, 5)) as 'Krótki login'
FROM Employee
wiczenie 2.23
Wy wietl imi , nazwisko oraz wiek wszystkich pracowników. Posortuj ich dane we-
d ug wieku, a je li istnieje wielu pracowników w tym samym wieku, posortuj ich we-
d ug nazwiska. Je li istnieje wielu pracowników w tym samym wieku i o tym samym
nazwisku, posortuj ich wed ug imienia.
Oczekiwany wynik
Rysunek 2.22.
Oczekiwany wynik
wiczenia 2.23
Rozwi zanie
Do obliczenia wieku pracownika u yjemy funkcji DATEDIFF, która policzy liczb lat,
jaka min a od daty urodzin (kolumna BirthDate) do dnia dzisiejszego (warto zwra-
cana przez funkcj GETDATE).