Avatar billede kinginkvong Nybegynder
27. august 2006 - 17:48 Der er 10 kommentarer

Problemer med anvendelse af LEFT JOIN?

Kan man anvende LEFT JOIN funktionen samtidig med WHERE, og i givet fald hvordan?

Hvis man ikke kan, hvordan foretager man sig så sammenføjninger mellem flere tabeller med JOIN funktionen?

The King in Kvong
Avatar billede arne_v Ekspert
27. august 2006 - 17:53 #1
hvorfor ikke ?
Avatar billede kjulius Novice
27. august 2006 - 18:13 #2
" X Kan man anvende LEFT JOIN funktionen samtidig med WHERE, og i givet fald hvordan?
"

Ja, det kan da godt. Man skal bare huske på, at felterne fra tabellen på højre side af en LEFT JOIN muligvis vil returnere null værdier, hvis der ikke findes rækker i tabellen som opfylder kriteriet fra ON delsætningen.

Hvis man derfor tester på et felt fra tabellen på den højre side af en LEFT JOIN, er man også nødt til at tillade null, ellers vil det virke som en INNER JOIN.

Eksempel:

SELECT tabel1.*, tabel2.*
FROM tabel1
LEFT JOIN tabel2 ON tabel1.felt1 = tabel2.felt1
WHERE tabel2.felt2 = 26

Det ser jo meget tilforladeligt ud, ikke?
Men der var jo en grund til at vi brugte en LEFT JOIN, ikke? Vi ønskede, at liste ALLE rækker i tabel1 med angivelse af felterne fra evt. tilsvarende rækker fra tabel2, hvor felt2 var 26.
Det er imidlertid ikke hvad vi får tilbage. Vi får kun de rækker fra tabel1, hvor der findes en tilsvarende række i tabel2, hvor felt2 er 26. Altså svarende til en ganske normal INNER JOIN.
Hvorfor nu det? Jo, du husker nok, at der blev returneret null værdier i felterne fra tabellen på den højre side af vor LEFT JOIN, ikke? Men det tager kriteriet i vor WHERE sætning ikke højde for. Vi er nødt til at tillade BÅDE værdien 26 og null, så hvis det skal virke efter hensigten skal vor sætning lyde:

SELECT tabel1.*, tabel2.*
FROM tabel1
LEFT JOIN tabel2 ON tabel1.felt1 = tabel2.felt1
WHERE (tabel2.felt2 = 26 OR tabel2.felt2 IS NULL)

En god regel at huske er der: Hvis der skal testes på et felt fra en tabel på den højre side af en LEFT JOIN, skal man også huske at tillade NULL for dette felt.
Avatar billede kinginkvong Nybegynder
27. august 2006 - 19:38 #3
HOv det var ikke de jeg ville poste.

her er det jeg ville skrive:


Det er godt du svare på den måde det antyder, at det kan lade sig gøre. Mit problem er, at jeg ikke aner hvordan syntaksen skal se ud.


Hvis jeg har:

SELECT field1, field2, field3
FROM table1
LEFT JOIN table2
ON table1.IDtable2 = table2.ID

Og:

SELECT field1, field2, field3
FROM table1, table3
WHERE table1.IDtable3 = table3.ID

Det Kan godt være jeg roder lidt rundt I begreberne men det er også første gang jeg har behov for, at anvende JOIN funktionen, håber at du nu aligevel kan hjælpe mig.
Avatar billede arne_v Ekspert
27. august 2006 - 20:09 #4
Lige ud af landevejen:

SELECT *
FROM t1 LEFT JOIN t2 ON t1.k=t2.k
WHERE t1.v=123

Men i dit eksempel er det jo en gammeldags komma join.

Jeg ville merge dem til:

SELECT field1, field2, field3
FROM (table1 LEFT JOIN table2 ON table1.IDtable2 = table2.ID)
      JOIN table3 ON table1.IDtable3 = table3.ID

da jeg ikke vil blande ny og gammel join

men du kan stadig:

SELECT field1, field2, field3
FROM (table1 LEFT JOIN table2 ON table1.IDtable2 = table2.ID)
      JOIN table3 ON table1.IDtable3 = table3.ID
WHERE tabel1.navn = 'ABC'
Avatar billede kjulius Novice
27. august 2006 - 21:47 #5
Din sætning

SELECT field1, field2, field3
FROM table1, table3
WHERE table1.IDtable3 = table3.ID

kan faktisk også skrives som

SELECT field1, field2, field3
FROM table1
CROSS JOIN table3
WHERE table1.IDtable3 = table3.ID

og er altså en såkaldt Cartesian Product join, som dog er blevet begrænset af en selektion i WHERE delen. Da denne selektion angiver felter fra begge tabeller, bliver det i realiteten til en INNER JOIN, og kan derfor også skrives som

SELECT field1, field2, field3
FROM table1
INNER JOIN table3 ON table1.IDtable3 = table3.ID

Derfor kan du efter denne omskrivning meget let, som arne skriver let "blande" disse to forespørgsler:

SELECT field1, field2, field3
FROM table1
INNER JOIN table3 ON table1.IDtable3 = table3.ID
LEFT JOIN table2 ON table1.IDtable2 = table2.ID

Som du kan se, er der med denne skrivemåde ikke længere brug for at skrive noget i WHERE delen, da alle relationerne er beskrevet på ON elementet.
Dermed være ikke sagt, at man ikke kan tilføje yderligere selektionskriterier, som jeg har beskrevet i mit tidligere indlæg.
Avatar billede kjulius Novice
27. august 2006 - 22:04 #6
Som arne også skriver (eller antyder) anser de fleste et format hvor man angiver en række tabeller separeret med komma, for gammeldags og en skrivemåde man bør undgå.

Et format hvor man direkte angiver den måde tabellerne skal joines og specifikt angiver relationerne på ON elementet er meget lettere at overskue og arbejde videre med. At bruge cartesian product metoden og angive relationskriterierne i WHERE delen kan hurtigt give et temmeligt uoverskueligt kriterie, især når man begynder at blande selektions- og relationskriterier.
Avatar billede arne_v Ekspert
30. august 2006 - 04:59 #7
faktisk bruger jeg selv ofte den gamle form

men LEFT JOIN er hverken standard eller køn i den gamle variant

og jeg vil aldrig aldrig blande den nye og den gamle form

og hvis man bruger den gamle form skal man naturligvis gruppere sine
WHERE betingelser i de to respektive grupper
Avatar billede arne_v Ekspert
30. september 2006 - 20:57 #8
kinginkvong ?
Avatar billede kinginkvong Nybegynder
01. oktober 2006 - 11:54 #9
Ja, jeg har læst jeres kommentar og fundet løst mit problem.

Jeg mangler bare at der bliver tilføjet et svar så jeg kan lukkke tråden.
Avatar billede kjulius Novice
01. oktober 2006 - 13:18 #10
Tja, så er vi tilbage til diskussionen om, hvilken konvention der skal bruges herinde. Den gængse mening på bjerget er, at indlæg fra interessenter skal afgives som kommentarer, indtil spørgeren angiver, at problemet er løst. Først på dette tidspunkt anses spørgsmålet som besvaret.

Denne fremgangsmåde giver selvsagt det problem, at når spørgeren har fået sit problem løst, er der endnu ikke afgivet et svar. Det er derfor op til spørgeren at angive, at den eller de personer, som har bidraget til løsningen af problemet (og det kan selvsagt bedst vurderes af spørgeren), bliver opfordret til at lægge et svar. Først herefter kan point fordeles og spørgsmålet lukkes.

Personligt er jeg ikke sikker på, at det er den optimale løsning, men som sagt er det den måde IDG, som står for driften af dette site, ønsker det.

http://expfaq.dk/vejledning_til_nye_brugere
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester