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