background image

Bazy Danych cz II

Zapytania z grupowaniem

I warunkiem NOT EXISTS

background image

Potrzeba grupowania

• Zapytania z funkcjami agreguj

ą

cymi s

ą

 

bardzo potrzebne ale chc

ą

c policzy

ć

 

ś

redni

ą

 pensj

ę

 w ka

ż

dej z firm trzeba:

– Napisa

ć

 program który w p

ę

tli, dla ka

ż

dej 

firmy wyliczy w niej 

ś

redni

ą

– Wynik b

ę

dzie zapisywał do tabeli 

tymczasowej

– Na ko

ń

cu wy

ś

wietli zawarto

ść

 tabeli 

tymczasowej

background image

Zapytanie z grupowaniem

• Chc

ą

c otrzyma

ć

 wspomniany uprzednio 

raport w jednym zapytaniu, nale

ż

skorzysta

ć

 z zapytania z grupowaniem

SELECT lista_kolumn, Funkcje_Agregujace

FROM tabele

WHERE warunki_na_wiersze

GROUP BY lista_kolumn

HAVING warunki_na_funkcje_agreguj

ą

ce

background image

Zasady grupowania

• Lista kolumn w klauzuli SELECT i GROUP 

BY musi by

ć

 taka sama

• Klauzula HAVING jest opcjonalna 

• Ide

ą

 zapytania jest: 

– Wylicz warto

ś

ci Funkcji Agreguj

ą

cych dla 

danej grupy (czyli powtarzaj

ą

cych si

ę

 warto

ś

ci 

w kolumnie)

background image

Grupowanie – Cwiczenie 1

SELECT id_osoby, id_firmy, stanowisko, pensja FROM Etaty  order by id_firmy, id_osoby

id_osoby    id_firmy stanowisko pensja      do         

----------- -------- ---------- ----------- ----------

1           FŁP      Kierownik  6200.0000   2004-10-22

4           FŁP      Prezes     65200.0000  NULL

1           HP       Konsultant 20000.0000  NULL

5           HP       Dyrektor   50000.0000  2002-10-21

1           PW       Magazynier 4200.0000   2004-10-22

1           PW       Doktorant  600.0000    1998-01-01

1           PW       Asystent   1600.0000   2000-01-01

1           PW       Adjunkt    3200.0000   NULL

1           PW       Sprz

ą

tacz  2200.0000   NULL

2           PW       Adjunkt    3200.0000   NULL

background image

Liczymy 

ś

redni

ą

 w całej bazie

• Zwykłe zapytanie z funkcjami agreguj

ą

cymi:

SELECT 

AVG(e.pensja) AS 

ś

r_w_bazie

COUNT(*)

AS ile_etatów

FROM Etaty e

ś

r_w_bazie            ile_etatów  

--------------------- -----------

15640.0000            10

background image

Ś

rednia pensja w firmach

SELECT e.id_firmy

,

avg(e.pensja) 

as 

ś

r_w_firmie

count(*) 

as ile_etatów_w_firmie 

FROM etaty e

GROUP BY e.id_firmy

id_firmy 

ś

r_w_firmie           ile_etatów_w_firmie 

-------- --------------------- -------------------

FŁP      35700.0000            2

HP       35000.0000            2

PW       2500.0000             6

background image

Dodanie kolumn, nie zmieniaj

ą

cych 

wyniku zapytania i jego logiki

S

ą

 to kolumny opisujace dodatkowo wybran

ą

 ju

ż

 

grup

ę

. W naszym przykładzie grupujemy „po 

firmach”. Dodanie dodatkowych kolumn opisuj

ą

cych 

Firmy nie zmieni logiki zapytania

SELECT e.id_firmy, f.nazwa, f.ulica

,

avg(e.pensja) 

as 

ś

r_w_firmie

count(*) 

as ile_etatów_w_firmie 

FROM etaty e join firmy f 

on (f.nazwa_skr = e.id_firmy)

GROUP BY e.id_firmy

, f.nazwa, f.ulica

id_firmy pelna_nazwa          ulica                

ś

r_w_firmie   ile_etatów_w_firmie 

-------- -------------------- -------------------- ------------- -------------------

FŁP      Fabryka Łodzi Podwod Na dnie 4            35700.0000    2

HP       Hewlett Packard      Szturmowa 2a         35000.0000    2

PW       Politechnika Warszaw Pl. Politechniki 1   2500.0000     6

background image

Kolumny zmieniaj

ą

ce logik

ę

 i wynik 

zapytania

Dodanie kolumny ID_OSOBY zmienia sens zapytania. Chcemy 

obejrze

ć

 

ś

redni

ą

 pensj

ę

 kazdej z osób w róznych firmach (jak 1 

osoba ma kilka etatów w firmie to policzy jej 

ś

r. Jak ma jeden to 

go poka

ż

e)

SELECT e.id_firmy, 

e.id_osoby

,

avg(e.pensja) 

as 

ś

r_p_osoby_w_firmie

count(*) 

as ile_etatów_osoby_firmie 

FROM etaty e

GROUP BY e.id_firmy, 

e.id_osoby

background image

Kolumny zmieniaj

ą

ce logik

ę

 i wynik 

zapytania - WYNIK

id_firmy id_osoby    

ś

r_p_osoby_   ile_etatów_osoby_firmie 

-------- ----------- ------------- -----------------------

FŁP      1           6200.0000             1

HP       1           20000.0000            1

PW       1           2360.0000             5

PW       2           3200.0000             1

FŁP      4           65200.0000            1

HP       5           50000.0000            1

• Logika została zmieniona – grupujemy dodatkowo po 

innej logicznej cało

ś

ci

• Osoba o ID = 1 ma 

ś

redni

ą

 pensj

ę

 w firmie ‘PW’ 

wyliczon

ą

 z jego 5 etatów na których pracuje 

(pracowała)

background image

Warunki na grup

ę

• Pokaza

ć

 maksymaln

ą

 pensje w ka

ż

dej z firm 

pod warunkiem, ze w firmie pracuje wi

ę

cej ni

ż

 

jedna osoba (to jest co innego ni

ż

 ilo

ść

 etatów):

SELECT e.id_firmy, MAX(e.pensja) AS maks_p

FROM Etaty e

WHERE (e.do IS NULL)

GROUP BY e.id_firmy

HAVING 

COUNT(DISTINCT ID_OSOBY) > 2

/* HAVING 

COUNT(*) > 2 

*/

background image

NOT EXISTS – zapytania 

wewn

ę

trzne (zagnie

ż

d

ż

one)

SELECT lista_kolumn_zapytania_głównego

FROM lista_tabel_zapytania_gł
WHERE [warunki_na_wiersze AND]
NOT EXISTS

(SELECT cokolwiek

FROM lista_tabel_wewn

ę

trznych

WHERE 

WARUNEK_Ł

Ą

CZ

Ą

CY_GŁ_Z_WEW

[ AND dodatkowe_war_na_wiersze_tab_wew]

)

background image

NOT EXITS - Przykład

• Pokaza

ć

 osoby, które nie maj

ą

 

aktualnie 

ż

adnego etatu

• Inaczej mówi

ą

c przeszukujemy tabel

ę

 

osób i po kolei -> dla ka

ż

dej z nich 

sprawdzamy:

– Istnieje dla tej osoby aktualny etat (jeden lub 

dowolna ich ilo

ść

, genralnie 

jakiekolwiek

)?

– Jak NIE to pokazujemy t

ę

 osob

ę

background image

NOT EXISTS – Przykład cd.

SELECT o.*

FROM osoby 

o

WHERE NOT EXISTS

( SELECT 1

FROM etaty ew

WHERE/* war ł

ą

cz

ą

cy*/

(ew.id_osoby = 

o

.id_osoby)

AND

(ew.do IS NULL) /*aktualne etaty*/

)

background image

NOT EXISTS – Przykład 2

• Pokaza

ć

 firmy w których nie pracuje aktualnie 

nikt mieszkaj

ą

cy w mie

ś

cie o nazwie Warszawa

• Przegladamy baz

ę

 firm i dla ka

ż

dej z nich 

sprawdzamy czy nie istniej

ą

 

w tej firmie

pracownicy maj

ą

cy aktualny etat i mieszkaj

ą

cy w 

Warszawie

– Mo

ż

e by

ć

 taki jeden, kilku lub wszyscy

– Wystarczy jak jest jeden -> to ju

ż

 firmy nie 

pokazujemy 

background image

NOT EXISTS – Przykład 2 cd.

SELECT f.nazwa_skr, f.nazwa, m.nazwa AS miasto_firmy

FROM firmy 

f

join miasta m ON (m.id_miasta=f.id_miasta)

WHERE NOT EXISTS

(SELECT 1

FROM etaty eW

join osoby oW ON (oW.id_osoby=eW.id_osoby)

join miasta mW ON (mW.id_miasta=oW.id_miasta)

WHERE

(eW.id_firmy = 

f

.nazwa_skr)

AND

(eW.do IS NULL) /* aktualne */

AND

(mW.nazwa = 'Warszawa')

)

nazwa_skr nazwa                          miasto_firmy                   

--------- ------------------------------ ------------

FŁP       Fabryka Łodzi Podwodnych       WARSZAWA

HP        Hewlett Packard                WARSZAWA

background image

NOT EXISTS z IF

/* usu

ń

 procedur

ę

 o nazwie Test – jak istnieje i utwórz na nowo */

IF EXISTS 

( SELECT 1 

FROM sysobjects o

/*tabela zawieraj

ą

ca obiekty w bazie*/

WHERE (o.[name] = 'Test')

/* nazwa obiektu */

AND

(OBJECTPROPERTY(o.[ID],'IsProcedure')=1)

)

BEGIN

DROP PROCEDURE Test

END

GO

CREATE PROCEDURE Test

AS

SELECT 'Hello'

GO

EXEC Test

background image

Procedura do usuwania procedur

/* Jak ju

ż

 istnieje takowa to usuwamy j

ą

 */

IF EXISTS 

(SELECT 1 

FROM sysobjects o

WHERE (o.[name] = 'UsunProc') AND
(OBJECTPROPERTY(o.[ID],'IsProcedure')=1)

)

BEGIN

DROP PROCEDURE UsunProc

END

GO

background image

Procedura do usuwania procedur -

definicja

CREATE PROCEDURE UsunProc (@proc nvarchar(100))

AS

DECLARE @stmt nvarchar(1000)

IF EXISTS

(SELECT 1 

FROM sysobjects o

WHERE

(o.[name] = @proc)

AND

(OBJECTPROPERTY(o.[ID], 'IsProcedure')=1)

)

BEGIN

SET @stmt = 'DROP PROCEDURE ' + @proc

EXEC sp_executeSql @stmt=@stmt

END

GO

background image

Procedura do usuwania procedur -

testowanie

• Wykonujemy trzy osobne działania. 

Poniewa

ż

 wcze

ś

niej stworzyli

ś

my 

procedur

ę

 

Test

to sprawdzamy, czy 

istnieje – uruchamiaj

ą

c j

ą

:

EXEC Test /*powinno dzialac*/

• Usuwamy stosuj

ą

c nasz

ą

 procedur

ę

:

EXEC UsunProc @proc = ‘Test’

• Sprawdzamy czy nadal Test istnieje

EXEC Test /*bł

ą

d – procedura nie isnieje*/

background image

Podsumowanie wiedzy -

Ć

wiczenie

Napisa

ć

 procedur

ę

, która zwróci 

ś

redni

ą

 

pensj

ę

 w kazdej z firm, maksymaln

ą

 i 

dane osoby która ma t

ę

 maksymaln

ą

Nale

ż

y pamieta

ć

ż

e tak jak w przypadku 

zapytania z funkcj

ą

 agreguj

ą

c

ą

 , nie da 

rady uzyska

ć

 wyniku w jednym zapytaniu

Wynik uzyskujemy w dwu krokach (z 
zapamietaniem po

ś

rednich wyników w 

tabeli tymczasowej)

background image

Ć

wiczenie posumowuj

ą

ce

Krok 1

Wybieramy zapytaniem z grupowaniem firmy i 

srednie i maksymalne pensje do tabeli 
roboczej #w

SELECT e.id_firmy

, AVG(e.pensja) AS sr_p

, MAX(e.pensja) AS max_p

, MIN(e.pensja) AS min_p 

INTO #w

FROM etaty e

WHERE

(e.do IS NULL)

GROUP BY e.id_firmy

background image

Tabel

ę

 tymczasow

ą

 łaczymy z 

etatami

SELECT LEFT(f.nazwa,30) AS Firma

,

#w.*

,

oMin.imi

ę

_i_nazwisko AS osoba_z_min_p

,

oMax.imi

ę

_i_nazwisko AS osoba_z_max_p

FROM firmy f

join #w ON (f.nazwa_skr = #w.id_firmy)

join etaty eMin ON 

(

(eMin.pensja = #w.min_p) 

AND 

(eMin.id_firmy=#w.id_firmy)

)

join etaty eMax ON 

(

(eMax.pensja=#w.max_p) 

AND 

(eMax.id_firmy=#w.id_firmy)

)

join osoby oMin ON (oMin.id_osoby=eMin.id_osoby)

join osoby oMax ON (oMax.id_osoby=eMax.id_osoby)

WHERE

(eMin.do IS NULL) AND (eMax.do IS NULL)

ORDER BY f.nazwa

background image

Ć

wiczenie - cało

ść

EXEC UsunProc @proc = 'StatystykiFirm'
GO
CREATE PROCEDURE StatystykiFirm
AS

SELECT e.id_firmy

AVG(e.pensja) AS sr_p

,

MAX(e.pensja) AS max_p

,

MIN(e.pensja) AS min_p INTO #w
FROM etaty e
WHERE

(e.do IS NULL)

GROUP BY e.id_firmy

SELECT  LEFT(f.nazwa,30) AS Firma
,

#w.*

,

oMin.imi

ę

_i_nazwisko AS osoba_z_min_p

,

oMax.imi

ę

_i_nazwisko AS osoba_z_max_p

FROM firmy f
join #w ON (f.nazwa_skr = #w.id_firmy)
join etaty eMin ON 

(

(eMin.pensja = #w.min_p) 

AND 

(eMin.id_firmy=#w.id_firmy)

)

join etaty eMax ON 

(

(eMax.pensja=#w.min_p) 

AND 

(eMax.id_firmy=#w.id_firmy)

)

join osoby oMin ON (oMin.id_osoby=eMin.id_osoby)
join osoby oMax ON (oMax.id_osoby=eMax.id_osoby)
WHERE

(eMin.do IS NULL) AND (eMax.do IS NULL)

ORDER BY f.nazwa

GO

background image

Ć

wiczenie – testowanie procedury

• Uruchomienie procedury

exec StatystykiFirm

• Wynik:

Firma             id_firmy sr_p       max_p      min_p      osoba_z_min_p osoba_z_max_p 

----------------- -------- ---------- ---------- ---------- ------------- -------------

Fabryka Łodzi Pod FŁP        65200.00   65200.00   65200.00 

K. Neptun     K. Neptun

Hewlett Packard   HP         20000.00   20000.00   20000.00 M. Stodolski  M. Stodolski

Politechnika Wars PW          2866.67    3200.00    2200.00 M. Stodolski  M. Stodolski

Politechnika Wars PW          2866.67    3200.00    2200.00 M. Stodolski  J. Korytkows

background image

Wstawianie rekordu do tabeli

• Dodanie nowej danej:

INSERT INTO etaty

id_firmy

,  id_osoby

,  stanowisko

,  od

,  pensja

) VALUES 

'FŁP'

,  1

,  'polerowacz wyrz.torped' 

, CONVERT(datetime, '20061101', 112)

, 2000

)

background image

Test po wstawieniu nowego 

wiersza

Firma             id_firmy sr_p       max_p      min_p      osoba_z_min_p osoba_z_max_p 

----------------- -------- ---------- ---------- ---------- ------------- -------------

Fabryka Łodzi Pod FŁP        33600.00   65200.00    2000.00 M. Stodolski  K. Neptun   

Hewlett Packard   HP         20000.00   20000.00   20000.00 M. Stodolski  M. Stodolski

Politechnika Wars PW          2866.67    3200.00    2200.00 M. Stodolski  M. Stodolski

Politechnika Wars PW          2866.67    3200.00    2200.00 M. Stodolski  J. Korytkows

• Politechnika wyst

ę

puje dwukrotnie, gdy

ż

 

ą

czenie #w i eMax daje dwa wiersze -> dwie 

osoby maj

ą

 takie same, maksymalne pensje. 

Dalsze zł

ą

czenie tych dwu osób z eMin daje 

ka

ż

dy z kazdym, czyli dwa wiersze

background image

Zmiana procedury

Rezygnujemy z pokazywania naraz osoby z min i max pensj

ą

ALTER PROCEDURE StatystykiFirm

AS

SELECT e.id_firmy

AVG(e.pensja) AS sr_p

,

MAX(e.pensja) AS max_p

,

MIN(e.pensja) AS min_p INTO #w

FROM etaty e

WHERE

(e.do IS NULL)

GROUP BY e.id_firmy

SELECT 

LEFT(f.nazwa,20) AS Firma

,

#w.id_firmy

,

STR(#w.sr_p,10,2) AS sr_p

,

STR(#w.max_p,10,2) AS max_p

,

STR(#w.min_p,10,2) AS min_p

,

LEFT(oMax.imi

ę

_i_nazwisko,12) AS osoba_z_max_p

FROM firmy f

join #w ON (f.nazwa_skr = #w.id_firmy)

join etaty eMax ON ((eMax.pensja=#w.max_p) AND (eMax.id_firmy=#w.id_firmy))

join osoby oMax ON (oMax.id_osoby=eMax.id_osoby)

WHERE

(eMax.do IS NULL)

ORDER BY f.nazwa

background image

Wynik poprawionej procedury

EXEC StatystykiFirm

Firma            id_firmy sr_p       max_p      min_p      osoba_z_max_p 

---------------- -------- ---------- ---------- ---------- -------------

Fabryka Łodzi Po FŁP        33600.00   65200.00    2000.00 K. Neptun   

Hewlett Packard  HP         20000.00   20000.00   20000.00 M. Stodolski

Politechnika War PW          2866.67    3200.00    2200.00 M. Stodolski

Politechnika War PW          2866.67    3200.00    2200.00 J. Korytkows

background image

Słownik cech

select c.*, wc.opis_wartosci AS opis

from cechy c 

join wartosci_cech wc 

ON (wc.id_cechy = c.id_cechy) 

order by c.id_cechy

id_cechy    opis_cechy                     jednowybieralna opis 

----------- ------------------------------ --------------- ---------

1           Bran

ż

a                         0               Komputery

1           Bran

ż

a                         0               Drukarki

1           Bran

ż

a                         0               Szkolenia

2           Odpowiedz na Akcj

ę

 Marketingow 1               NIE

2           Odpowiedz na Akcj

ę

 Marketingow 1               TAK

background image

Zasady projektowania efektywnych 

baz

• Wszystkie tabele projektowa

ć

 zgodnie ze sztuk

ą

– Ka

ż

da z kluczem głownym

– Klucze obce

– Unika

ć

 automatycznych mechanizmów kaskadowych

• Rzeczy, cechy których nie przewidzimy – da

ć

 

mozliwo

ś

c definiowania ich przez u

ż

ytkownika

– Budujemy słownik cech

– Słownik mo

ż

liwych warto

ś

c

– Tabel

ę

 wybranych cech

background image

Rozbudowa Bazy testowej

C E C H Y

id _C E C H Y

O p is_c e c h y

j e d n o w y b ie r a ln a

e ta ty

id _o so b y

id _fir m y

sta n o w isk o

p e n sj a

o d

d o

id _e ta tu

f i r m y  *

n a zw a _sk r

id _m ia sta

n a zw a

k o d _p o c zto w y

u lic a

F I R M Y _ C E C H Y  *

id _w a r to sc i

id _fir m y

m i a s ta

id _m ia sta

k o d _w o j

n a zw a

o s o b y

id _o so b y

id _m ia sta

im ię

n a zw isk o

im ię _i_n a zw isk o

d a ta _u r

w ie k

W A R T O S C I _ C E C H

id _w a r to sc i

id _C E C H Y

O p is_w a r to sc i

w o j

k o d _w o j

n a zw a

background image

Przeciez ka

ż

d

ą

 kolumn

ę

 da si

ę

 

zdefiniowa

ć

 jako cech

ę

 w słowniku

• TAK baza staje si

ę

 wtedy elestyczna ALE:

– Aplikacja bardzo trudna w realizacji
– Bardzo trudne zachowanie integralno

ś

ci bazy

– Znacznie mniej efektywne zapytania 

• Dlatego nale

ż

y zdefiniowa

ć

 tabele ze wszystkimi 

waznymi (i mniej waznymi) kolumnami, które 
mog

ą

 by

ć

 wykorzystane na ekranach, raportach, 

wydrukach

• Słownik cech traktowa

ć

 jako narz

ę

dzie do np. 

wyszukiwania danych, statystyk

background image

Przykładowe dane:

SELECT fc.id_firmy, LEFT(c.opis_cechy,30) AS Cecha

,

LEFT(wc.opis_wartosci,10) AS wartosc, c.id_cechy

,  wc.id_wartosci AS idw

FROM firmy_cechy fc 

join wartosci_cech wc on (wc.id_wartosci=fc.id_wartosci)

join cechy c on (c.id_cechy = wc.id_cechy)

id_firmy Cecha                          wartosc    id_cechy  idw

-------- ------------------------------ ---------- -------- ----

HP       Bran

ż

a                         Komputery  1           1

HP       Bran

ż

a                         Drukarki   1           2

HP       Bran

ż

a                         Szkolenia  1           3

PW       Bran

ż

a                         Szkolenia  1           3

FŁP      Odpowiedz na Akcj

ę

 Marketingow TAK        2           5

HP       Odpowiedz na Akcj

ę

 Marketingow TAK        2           5

background image

Jak znale

źć

 dane spełniaj

ą

ce kilka 

cech ?

Np. Bran

ż

a -> Szkolenia, Na akcj

ę

 -> TAK:

SELECT fc.id_firmy, LEFT(c.opis_cechy,30) AS Cecha

, LEFT(wc.opis_wartosci,10) AS wartosc,

c.id_cechy

,  wc.id_wartosci AS idw

FROM firmy_cechy fc 

join wartosci_cech wc on 
(wc.id_wartosci=fc.id_wartosci)

join cechy c on (c.id_cechy = wc.id_cechy)

WHERE

(c.id_cechy = 1 AND wc.id_wartosci=3)

AND

(c.id_cechy = 2 AND wc.id_wartosci=5)

Wynik zapytania PUSTY. Nie jest mo

ż

liwe 

ż

eby w jednym 

wierszu jedo pole miało zarówno warto

ść

 1 jak i 2 

JEDNOCZE

Ś

NIE

background image

Poprawne zapytanie

SELECT fc.id_firmy, LEFT(c.opis_cechy,30) AS Cecha

, LEFT(wc.opis_wartosci,10) AS wartosc,c.id_cechy

,  wc.id_wartosci AS idw

FROM firmy_cechy fc join wartosci_cech wc 

on (wc.id_wartosci=fc.id_wartosci)

join cechy c on (c.id_cechy = wc.id_cechy)

WHERE

(c.id_cechy = 1 AND wc.id_wartosci=3)

OR

(c.id_cechy = 2 AND wc.id_wartosci=5) 

id_firmy Cecha                         wartosc    id_cechy    idw         

-------- ----------------------------- ---------- ----------- ---

FŁP      Odpowiedz na Akcj

ę

 Marketigow TAK        2           5

HP       Odpowiedz na Akcj

ę

 Marketngow TAK        2           5

HP       Bran

ż

a                        Szkolenia  1           3

PW       Bran

ż

a                        Szkolenia  1           3

background image

Szukanie danych spełniaj

ą

cych 

cechy

• Szukamy N róznych warto

ś

ci cech

• Je

ż

eli firma X ma je wszystkie to w wyniku 

zapytania wyst

ą

pi tyle razy ilu cech 

szukamy

• Wystarczy skorzysta

ć

 z umiej

ę

tno

ś

ci 

grupowania danych z dodatkowym 
warunkiem HAVING. 

• Liczymy z ilu rekordów składa si

ę

 grupa.

background image

Procedura szukania danych 

posiadaj

ą

cych wybrane cechy

EXEC UsunProc 'FirmyMajaceCechy'

GO

CREATE PROCEDURE FirmyMajaceCechy

AS

DECLARE @ile_cech int

SELECT @ile_cech = COUNT(*) FROM #wc

SELECT 

f.nazwa_skr, f.nazwa

FROM firmy f join firmy_cechy fc 

ON (f.nazwa_skr = fc.id_firmy)

join wartosci_cech wc

on (wc.id_wartosci=fc.id_wartosci)

join #wc ON (#wc.id_wartosci=wc.id_wartosci)

GROUP BY 

f.nazwa_skr, f.nazwa

HAVING COUNT(*) = @ile_cech

GO

background image

Testowanie Procedury

• Tworzymy tymczasow

ą

 tabel

ę

 i wstawiamy 

do niej szukane warto

ś

ci cech

CREATE TABLE #wc (id_wartosci int not null)

INSERT INTO #wc (id_wartosci) VALUES (5)

INSERT INTO #wc (id_wartosci) VALUES (3)

EXEC FirmyMajaceCechy

• Uzyskany wynik:

nazwa_skr nazwa                          

--------- ------------------------------

HP        Hewlett Packard

background image

„Klejenie” wyników zapyta

ń

• Naszym zadaniam jest pokazanie osób, które 

nigdzie aktualnie nie pracuj

ą

 i pracuj

ą

cych 

aktualnie wraz z ich pensjami na jednym 
raporcie

• Skorzystami z mozliwo

ś

ci „klejenia” zapyta

ń

 

UNION

• Zapytania musz

ą

 mie

ć

 tak

ą

 sam

ą

 ilo

ść

 kolumn, 

takich samych typów

• Kolumny wynikowe przyjm

ą

 nazwy kolumn z 

pierwszego zapytania

background image

Ć

wiczenie na UNION

• Pokaza

ć

 nazwy województw i miast w bazie oraz 

województwa bez wpisanych miast

SELECT w.kod_woj, w.nazwa AS Woj, m.nazwa AS Miasto

FROM woj w join miasta m ON (w.kod_woj=m.kod_woj)

UNION ALL /*bez ALL SQL wybierze wszystkie wiersze z 1 

pytania i te z drugiego, których nie było w pierwszym*/

SELECT w.kod_woj, w.nazwa, '<Brak miast>'

FROM woj w

WHERE NOT EXISTS 

( SELECT 1

FROM Miasta mw 

WHERE

(mw.kod_woj = w.kod_woj)

)

ORDER BY 

2 /*mo

ż

na tylko podawa

ć

 numery kolumn*/

background image

Wynik 

ć

wiczenia z UNION

kod_woj Woj                            Miasto       

------- ------------------------------ ------------

???     <Nieznane>                     <Brak miast>

Maz     Mazowieckie                    WESOŁA

Maz     Mazowieckie                    WARSZAWA

Pom     Pomorskie                      GDA

Ń

SK

Pom     Pomorskie                      SOPOT

• WNIOSKI

:

– Połaczenie dwóc tabel w zapytaniu SELECT 

ze sob

ą

 daje w wyniku tylko wiersze, które 

maj

ą

 odpowiedniki w obydwu tabelach

background image

ą

czenia „otwarte”

• Je

ż

eli chcemy w wniku zapytania uzyska

ć

 

wszystkie wiersze z jednej tabeli i ew. 
odpowiadaj

ą

ce im wiersze z drugiej tabeli 

to nale

ż

y u

ż

y

ć

 zł

ą

czenia lewostronnie 

otwartego :O 

SELECT w.*, m.nazwa AS miasto

FROM woj w 

LEFT OUTER join

miasta m

ON (w.kod_woj = m.kod_woj)

background image

Wynik zł

ą

czenia „otwartego”

• Jak nie ma odpowiedników w drugiej tabeli to 

SQL pokazuje NULL

kod_woj nazwa        miasto                         

------- ------------ ---------

???     <Nieznane>   

NULL

Maz     Mazowieckie  WESOŁA

Maz     Mazowieckie  WARSZAWA

Pom     Pomorskie    GDA

Ń

SK

Pom     Pomorskie    SOPOT

background image

Zapytaie, które zwróci ten sam 

wynik co UNION

SELECT w.kod_woj, w.nazwa

ISNULL(m.nazwa,'<Brak miast>')

AS miasto

FROM woj w 

LEFT OUTER join

miasta m

ON (w.kod_woj = m.kod_woj)

kod_woj nazwa        miasto       

------- ------------ ------------

???     <Nieznane>   <Brak miast>

Maz     Mazowieckie  WESOŁA

Maz     Mazowieckie  WARSZAWA

Pom     Pomorskie    GDA

Ń

SK

Pom     Pomorskie    SOPOT