[php & sql] query geeft verkeerde tabel weer

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Beste mensen,

Ik ben bezig met een script dat de laatste 5 database items weergeeft inclusief de bijbehorende foto die bij de item hoort.
Hiervoor worden twee tabellen aangeroepen (admin_aquawish en admin_foto).

Nu heb ik hetvolgende:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<? 
$select = mysql_query(" 
SELECT 
admin_aquawish.*, 
admin_foto.* 
FROM admin_aquawish 
LEFT JOIN admin_foto 
ON admin_foto.foto_id2 = admin_aquawish.aquawish_id 
WHERE 
aquawish_soortreactie='vis' OR 
aquawish_soortreactie='plant' OR 
aquawish_soortreactie='ongewerveld' 
ORDER BY 
aquawish_id 
DESC LIMIT 5") or die("er is iets fout! " . mysql_error()); 

while ($row = mysql_fetch_assoc ($select)) 
{ 

?>  


Echter geeft dit niet de laatste 5 waardes uit admin_aquawish weer, maar de laatste 5 waardes uit admin_foto.
Weet iemand hoe ik dit kan oplossen, want ik weet niet wat ik fout doe.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb het probleem gevonden. Er waren meerdere foto's met dezelfde id2, want een aquawish item kan meerdere foto's hebben. Ik heb alle foto's nu uniek gemaakt door ze een nummer te geven en ze daarmee aan te roepen, en nu werkt het goed.
Echter stuit ik op een nieuw probleem. Met de volgende query geeft hij alleen de items uit tabel admin_aquawish weer die een foto heeft. Maak ik een item aan waar ik nog geen foto voor heb, dan wordt deze niet weergegeven.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?  
$select = mysql_query("  
SELECT  
admin_aquawish.*,  
admin_foto.*  
FROM admin_aquawish
LEFT JOIN admin_foto  
ON admin_foto.foto_id2 = admin_aquawish.aquawish_id
WHERE
admin_foto.foto_nr = '1' AND  
admin_aquawish.aquawish_soortreactie='plant' OR
admin_foto.foto_nr = '1' AND
admin_aquawish.aquawish_soortreactie='vis' OR
admin_foto.foto_nr = '1' AND
admin_aquawish.aquawish_soortreactie='ongewerveld' 
ORDER BY  
admin_aquawish.aquawish_id  
DESC LIMIT 5") or die("er is iets fout! " . mysql_error());  

while ($row = mysql_fetch_assoc ($select))  
{  

?>


Ik wil eigenlijk dat alle laatste 5 items uit tabel admin_aquawish worden weergegeven, ongeacht die item een foto heeft of niet. Heeft het wel een foto, dan moet deze weergegeven worden.

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Leuk die query, maar met slechte tabellen kun je beter eerst de tabellen optimaliseren. Waarom hebben foto's bijvoorbeeld twee id's?
De WHERE-clausule kan met wat haakjes een stuk eenvoudiger. Bovendien hoef je bij foto_nr, dat een getal is, geen stringtekens te gebruiken.
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT  
admin_aquawish.*,  
admin_foto.*  
FROM admin_aquawish
LEFT JOIN admin_foto  
ON admin_foto.foto_id2 = admin_aquawish.aquawish_id
WHERE
admin_foto.foto_nr = 1 AND 
(admin_aquawish.aquawish_soortreactie='plant' OR
admin_aquawish.aquawish_soortreactie='vis' OR
admin_aquawish.aquawish_soortreactie='ongewerveld')
ORDER BY  
admin_aquawish.aquawish_id  
DESC LIMIT 5

De fout die je hier maakt, is dat je eerst de JOIN uitvoert, en daarna nog controleert of het foto_nr gelijk is aan 1. Bestaat de foto niet, dan zal foto_nr nooit gelijk zijn aan 1, en krijg je dus inderdaad niet de rijen terug zonder foto. Je LEFT JOIN moet dus iets anders:
SQL:
1
ON (admin_foto.foto_id2 = admin_aquawish.aquawish_id AND admin_foto.foto_nr=1)

Het controleren op foto_nr kan daarna weg uit de WHERE-clausule.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Super bedankt,
Waarvoor dienen die haakjes precies bij de WHERE want dat begreep ik niet helemaal.

Acties:
  • 0 Henk 'm!

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Dat heeft te maken met de prioriteit van de operators AND en OR. Net als vermenigvuldigen en optellen als het ware. De ANDs worden eerst afgehandeld, dan pas de ORs.

Info over boolean logica:
http://www.lib.csubak.edu/infocomp/search/boolean/venn.htm

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
In dit geval kon je trouwens ook IN gebruiken. Ik weet niet of het sneller gaat, maar het ziet er wel wat overzichtelijker uit.
SQL:
1
2
3
4
5
6
7
8
9
10
11
SELECT  
admin_aquawish.*,  
admin_foto.*  
FROM admin_aquawish
LEFT JOIN admin_foto  
ON (admin_foto.foto_id2 = admin_aquawish.aquawish_id AND admin_foto.foto_nr=1)
WHERE
admin_aquawish.aquawish_soortreactie IN ('plant', 'vis', 'ongewerveld')
ORDER BY  
admin_aquawish.aquawish_id  
DESC LIMIT 5
Pagina: 1