| 
					
							
        
    
        
						
			 | 
			
			
					    
					
        
         
          
         
	
            | 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 
 
 
  
            
             |   |   
            
        
 
    
 
					
					 
			 | 
			
				
        
			 |