webForumDet fria alternativet

Left join?

8 svar · 303 visningar · startad av Ankman

AnkmanMedlem sedan juni 2002115 inlägg
#1

Jag vill välja alla rader från records som stämmer med villkoret artist_id och om det finns en motsvarande rad i record_grades som även stämmer med record_grades.user_id vill jag ha med den också. Om det inte finns någon post som stämmer i record_grades skall grade vara NULL i resultatet.
Det finns aldrig mer än en post i record_grades som hör ihop med posten i records.

Den här SQL-satset funkar inte så bra då den bara ger resultat om det finns rader i bägge tabellerna men den kanske kan illustrera vad jag vill åt.

$query =   "SELECT records.*, record_grades.grade
 				FROM
 					records
 				LEFT JOIN
 					record_grades
 				ON
 					records.id = record_grades.record_id
 				WHERE
 					records.artist_id = $artist_id
 				AND
 					record_grades.user_id = $this->logged_in_user_id
 				ORDER BY
	 				records.release_year
 				";

Någon som har koll på detta och vill hjälpa till lite?

Engine^Medlem sedan dec. 20002 861 inlägg
#2

Det beror på din WHERE-klausul.

AND record_grades.user_id = $this->logged_in_user_id

Det borde ju kunna gå att lösa med att flytta upp det villkoret i JOIN-delen

SELECT r.*, rg.grade
FROM records r
LEFT JOIN record_grades rg
  ON rg.record_id = r.id AND rg.user_id = $this->logged_in_user_id
ORDER BY r.release_year
PDahlenMedlem sedan apr. 2004784 inlägg
#3

Blev inte det där samma som den första? ;)

Använd LEFT OUTER JOIN så borde det funka.

@ndersMedlem sedan juni 200026 914 inlägg
#4

PDahlen skrev:

Använd LEFT OUTER JOIN så borde det funka.

LEFT OUTER JOIN är samma sak som LEFT JOIN. :)

Mvh

PDahlenMedlem sedan apr. 2004784 inlägg
#5

Jo, det stämmer men när jag lägger in LEFT JOIN i VS.NET och testar så lägger den till OUTER så du kan ju prova.
Ser även en annan sak. Det borde vara WHERE inte AND eftersom loginkollen skall göras på hela resultatet och inte på JOINen. Nedanstående returnerar korrekt resultat när jag testar. Det gjorde den däremot inte med AND.

SELECT r.*, rg.grade
FROM records r
LEFT OUTER JOIN record_grades rg
  ON rg.record_id = r.id
WHERE rg.user_id = $this->logged_in_user_id
ORDER BY r.release_year

Så lägg till OUTER och testa om det blir någon skillnad.

Engine^Medlem sedan dec. 20002 861 inlägg
#6

OUTER är som @nders påpekade optional enligt SQL-syntaxstandard och ska inte göra någon skillnad.

Att ha med

WHERE rg.user_id = $this->logged_in_user_id

gör ju LEFT JOIN verkningslös om jag förstår tabelldesignen rätt. Även om skivan inte har något betyg så ska den vara med i SQL-resultatet.

Jag missade dock en liten WHERE-snutt i mitt svar...

SELECT r.*, rg.grade
FROM records r
LEFT JOIN record_grades rg
  ON rg.record_id = r.id AND rg.user_id = $this->logged_in_user_id
WHERE r.artist_id = $artist_id
ORDER BY r.release_year

Men eftersom jag inte är något ess på SQL förbehåller jag mig rätten att dementera allt jag svarar... ;)

PDahlenMedlem sedan apr. 2004784 inlägg
#7

Sorry, jag som inte läste första inlägget ordentligt.
Engines sista SQL kod är den korrekta lösningen.

AnkmanMedlem sedan juni 2002115 inlägg
#8

Engine^: ypperligt, tackar.

Engine^Medlem sedan dec. 20002 861 inlägg
#9

Bockar. :)

Genererad på 371 ms · cache AV · v20260730165559-full.f96bc7eb