/ Forside / Teknologi / Udvikling / SQL / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
join og sum over flere tabeller
Fra : Leif Neland


Dato : 18-03-08 15:35

Hvordan kan man i et enkelt query lave joins med flere tabeller og summere
op?
Hvor der er flere "en-til-mange" relationer til den samme "en" tabel.
Et eksempel, hvor der til hver vare er et antal købsordrer og et antal
salgsordrer.

Tabeller
Vare
vareid
varenavn
Eks:
vand01 Cola
vand02 squash
vand03 évian

Salgsordre
ordrenr
vareid
antal
Eks
0001 vand01 20
0002 vand01 30
0002 vand02 10

Købsordre
ordrenr
vareid
antal
01 vand01 50
02 vand01 30

Hvis jeg vil lave en tabel over hvor meget hver enkelt vare har solgt:
select varenavn,sum(salgsordre.antal) as salgstal from vare left join
salgsordre on vare.vareid=salgsordre.vareid
Så får jeg fint
Cola 50
squash 10
évian

Jeg kan lave det tilsvarende for indkøb og få
Cola 80
osv

Men hvis jeg joiner alle 3 tabeller, går det galt, fordi jeg får alle
kombinationer af salgs- og købs-ordrer for hver vare.
select varenavn,sum(salgsordre.antal) as salgstal,sum(købsordre.antal) as
købstal
from vare left join salgsordre on vare.vareid=salgsordre.vareid
left join købsordre on vare.vareid=købsordre.vareid

Altså for cola bliver det, der bliver summeret
Salgsordre salgsantal købsordre købsantal
0001 20 01 50
0001 20 02 30
0002 30 01 50
0002 30 02 30

Altså samlet salg 100 og indkøb 160, altså det dobbelte.
Og jeg kan jo ikke dividere salgsantal med antallet af købsordrer og
købsantallet med antallet af salgsordrer, fordi antallet af salgsordrer jo
kan være 0 for en vare, hvor der er købsordrer.

Kan man overhovedet kombinere det i et query?
For det er noget tungt at for hvert række i det ene query at lave et
subquery.
Måske et view?

Leif



 
 
Michael Zedeler (19-03-2008)
Kommentar
Fra : Michael Zedeler


Dato : 19-03-08 10:37

Leif Neland wrote:
> Hvordan kan man i et enkelt query lave joins med flere tabeller og summere
> op? [...]
> Kan man overhovedet kombinere det i et query?

Ja. Med subselect:

SELECT vare.id,
(SELECT SUM(pris)
FROM købsordre
WHERE købsordre.vare = vare.id)),
(SELECT SUM(pris)
FROM salgsordre
WHERE salgsordre.vare = vare.id)),
FROM vare

> For det er noget tungt at for hvert række i det ene query at lave et
> subquery.

Det burde det ikke være. Hvis du bruger en ordentlig database (og husker
at indeksere fremmednøglerne(!)), bør den godt kunne optimere
forespørgslen så det kører rimelig hurtigt.

> Måske et view?

Et view er ikke andet end en forespørgsel, så det ændrer ikke noget.

Mvh. Michael.

N/A (19-03-2008)
Kommentar
Fra : N/A


Dato : 19-03-08 11:04



Leif Neland (19-03-2008)
Kommentar
Fra : Leif Neland


Dato : 19-03-08 11:04


"Michael Zedeler" <michael@zedeler.dk> skrev i en meddelelse
news:TY4Ej.4$Hl2.2@news.get2net.dk...
> Leif Neland wrote:
> > Hvordan kan man i et enkelt query lave joins med flere tabeller og
summere
> > op? [...]
> > Kan man overhovedet kombinere det i et query?
>
> Ja. Med subselect:
>
> SELECT vare.id,
> (SELECT SUM(pris)
> FROM købsordre
> WHERE købsordre.vare = vare.id)),
> (SELECT SUM(pris)
> FROM købsordre
> WHERE salgsordre.vare = vare.id)),
> FROM vare
>
Det funger meget fint!

> > For det er noget tungt at for hvert række i det ene query at lave et
> > subquery.
>
> Det burde det ikke være. Hvis du bruger en ordentlig database (og husker
> at indeksere fremmednøglerne(!)), bør den godt kunne optimere
> forespørgslen så det kører rimelig hurtigt.
>
Jeg tror problemet har været, at jeg for hver række i det yderste query
lavede et nyt request i asp, således at der blev lavet 4000 queries mellem
webserveren og databaseserveren.

På den ny måde laves der kun et request.

Leif



Michael Zedeler (19-03-2008)
Kommentar
Fra : Michael Zedeler


Dato : 19-03-08 11:21

Leif Neland wrote:
> "Michael Zedeler" <michael@zedeler.dk> skrev i en meddelelse
> news:TY4Ej.4$Hl2.2@news.get2net.dk...
>> Leif Neland wrote:
>>> For det er noget tungt at for hvert række i det ene query at lave et
>>> subquery.
>> Det burde det ikke være. Hvis du bruger en ordentlig database (og husker
>> at indeksere fremmednøglerne(!)), bør den godt kunne optimere
>> forespørgslen så det kører rimelig hurtigt.
>>
> Jeg tror problemet har været, at jeg for hver række i det yderste query
> lavede et nyt request i asp, således at der blev lavet 4000 queries mellem
> webserveren og databaseserveren.

Ja. Se det er så en helt anden sag. Når du skriver "subquery" tror jeg
jo du mener "subselect". Hvis du laver en masse queries af den type, er
det næsten lige meget hvad du laver - det vil altid blive meget langsomt.

Mvh. Michael.


Kristian Damm Jensen (19-03-2008)
Kommentar
Fra : Kristian Damm Jensen


Dato : 19-03-08 13:46

Leif Neland wrote:
> Hvordan kan man i et enkelt query lave joins med flere tabeller og
> summere op?
> Hvor der er flere "en-til-mange" relationer til den samme "en" tabel.
> Et eksempel, hvor der til hver vare er et antal købsordrer og et antal
> salgsordrer.
>
> Tabeller
> Vare
> vareid
> varenavn
> Eks:
> vand01 Cola
> vand02 squash
> vand03 évian
>
> Salgsordre
> ordrenr
> vareid
> antal
> Eks
> 0001 vand01 20
> 0002 vand01 30
> 0002 vand02 10
>
> Købsordre
> ordrenr
> vareid
> antal
> 01 vand01 50
> 02 vand01 30
>
> Hvis jeg vil lave en tabel over hvor meget hver enkelt vare har solgt:
> select varenavn,sum(salgsordre.antal) as salgstal from vare left join
> salgsordre on vare.vareid=salgsordre.vareid
> Så får jeg fint
> Cola 50
> squash 10
> évian
>
> Jeg kan lave det tilsvarende for indkøb og få
> Cola 80
> osv
>
> Men hvis jeg joiner alle 3 tabeller, går det galt, fordi jeg får alle
> kombinationer af salgs- og købs-ordrer for hver vare.
> select varenavn,sum(salgsordre.antal) as
> salgstal,sum(købsordre.antal) as købstal
> from vare left join salgsordre on vare.vareid=salgsordre.vareid
> left join købsordre on vare.vareid=købsordre.vareid
>
> Altså for cola bliver det, der bliver summeret
> Salgsordre salgsantal købsordre købsantal
> 0001 20 01 50
> 0001 20 02 30
> 0002 30 01 50
> 0002 30 02 30
>
> Altså samlet salg 100 og indkøb 160, altså det dobbelte.
> Og jeg kan jo ikke dividere salgsantal med antallet af købsordrer og
> købsantallet med antallet af salgsordrer, fordi antallet af
> salgsordrer jo kan være 0 for en vare, hvor der er købsordrer.
>
> Kan man overhovedet kombinere det i et query?

Nej. Du prøver at kombinere oplysninger, der i bund og grund er urelaterede.
Det kan man slippe af sted med nogle gange, men ikke i dette tilfælde. Og så
alligevel....

> For det er noget tungt at for hvert række i det ene query at lave et
> subquery.

Næh, men prøv::

select Salg.varenavn, salgstal, købstal
from
(select varenavn,sum(salgsordre.antal) as salgstal
from vare left
join salgsordre
on vare.vareid=salgsordre.vareid) as Salg
join
(select varenavn,sum(købsordre.antal) as købstal
from vare left
left join købsordre
on vare.vareid=købsordre.vareid) as Køb
on Salg.varenavn=Køb.varenavn

> Måske et view?

Et view er ikke andet end en prædefineret subselect. Dér vinder du ikke
noget.

--
Venlig hilsen /Best regards
Kristian Damm Jensen



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408914
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste