Co mam spatne v SQL dotazu?

Jan Serak sherry na pikebo.cz
Úterý Říjen 10 11:40:46 CEST 2000


"Ing. Jiri Sika - Senior Web Programmer" wrote:
> 
>     Zdravim,
> snad mi tady nekdo poradi.
>   Mam tri tabulky prvni "Klienti" je zakladni (cislo_klienta,
> jmeno_klienta). Pak jsou dve doplnkove. "Knizky" a "Kazety"
> (cislo_zbozi, cislo_klienta, cena). Jak zapsat dotaz, ktery mi
> poskytne vysledek typu "Karel ma 5 knih za 100 kc a 6 kazet za
> 1000 Kc."?
> Zkusil jsem:
> 
> select Klienti.jmeno_klienta ,
>         count(Knizky.cena) ,
>         sum(Knizky.cena) ,
>         count(Kazety.cena) ,
>         sum(Kazety.cena)
> from Klienti
> left join Knizky
>         on Klienti.cislo_klienta=Knizky.cislo_klienta
> left join Kazety
>         on Klienti.cislo_klienta=Kazety.cislo_klienta
> group by Klienti.cislo_klienta;
> 
> A misto vyse uvedene odpovedi dostanu nasledujici: "Karel ma 30
> knih za 600 kc a 30 kazet za 5000 Kc." Zkratka vse u Kazet je
> pronasobene poctem Knih a naopak.

Myslim, ze to tu uz parkrat bylo. To je presne definice joinu:
podmnozina kartezskeho soucinu spojujici takove prvky patrici
do jednotlivych komponent, ktere maji nejaky atribut shodny.
Pokud vypustite ty sumy, ziskate presne to, co uvedenym
dotazem chcete ziskat:

	Karel	kniha_1	cena_knihy_1	kazeta_1	cena_kazety_1
	Karel	kniha_1	cena_knihy_1	kazeta_2	cena_kazety_2
	Karel	....
	Karel	kniha_2 cena_knihy_2	kazeta_1	cena_kazety_1
	Karel	kniha_2 cena_knihy_2	kazeta_2	cena_kazety_2
	Karel   ....
	Karel	kniha_m	cena_knihy_m	kazeta_n	cena_kazety_n

Pokud chcete ziskat pocet knih a pocet kazet, je treba dotaz preformulovat.
Nejjednodussi je rozdelit to na dva dotazy. Nebo resenim pres dve view:

	create view knihy_agr as
	select cislo_klienta,count(*) pocet_knih,sum(cena) cena_knih
	from knizky
	group by cislo_klienta;
	
	analogicky kazety_agr

	select
jmeno_klienta,nvl(pocet_knih,0),nvl(cena_knih,0),nvl(pocet_kazet,0),nvl(cena_kazet,0)
	from klienti,knihy_agr,kazety_agr
	where klienti.cislo_klienta=knihy_agr.cislo_klienta(+)
	and klienti.cislo_klienta=kazety_agr.cislo_klienta(+);

Jelikoz klient nemusi mit zadnou knihu nebo zadnou kazetu, je potreba jeste
udelat outer join. Neznam notaci MySQL a pouzil jsem oraclovskou (totez plati
pro nvl()). Na principu to ovsem nic nemeni.

							Jan Serak


Další informace o konferenci Test