Archief - MYSQL: problemen met inner join en php

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

`SeriOUs

Legacy Member
Ik zal het probleem adhv een voorbeeld proberen uit te leggen.

Ik heb 2 tables:
- tbllinks (id, classid, link, referrer)
- tblclass (id, class)

PHP:
$result = mysql_query("
   SELECT * FROM tbllinks 
   INNER JOIN tblclass 
   ON tbllinks.classid = tblclass.id
") or die(mysql_error());
while ($links = mysql_fetch_array($result)) {
   echo "$links[id]";
}
De id's die nu worden getoond zijn die van tblclass, en niet van tbllinks?
Enig idee hoe ik dat verhelpt, zonder echt de opgegeven velden in de SELECT mee te geven?

xml

Legacy Member
Dat gaat niet vrees ik? Het is trouwens sowieso beter je velden op te sommen in plaats van * te gebruiken.

*edit: m'n "ervaring" heeft me trouwens ook geleert van niet altijd gewoon "id" te nemen voor een sleutelveld, maar iets "unieker" zoals bvb "link_id" en "class_id". Dan zou je dit probleem ook niet gehad hebben en het is bovendien veel duidelijke in je code over wat het nu precies gaat.

Fr3aK

Legacy Member
PHP:
$result = mysql_query("
   SELECT l.id FROM tbllinks l
   INNER JOIN tblclass c
   ON l.classid = c.id
") or die(mysql_error());
while ($links = mysql_fetch_array($result)) {
   echo "$links[id]";
}
Probeer zo weinig mogelijk te selecteren met *, het verbuikt te veel geheugen en is niet zo handig met JOINS.

Joriz

Legacy Member
ik zou je tabel aanpassen naar

Links: lin_id | cla_id | lin_link | lin_referrer
Class: cla_id | cla_class

zoals je ziet herken je snel welke waarde van welke tabel komt en waar die dan ook in kan gejoined worden. gebruik als voorzetsel niet te grote voorzetsels (2 vind ik te weinig, 3 meestal voldoende, 4 kan ook, 5 vind ik al groot). Gebruik het voorzetsel voor elke waarde die enkel in deze tabel zal te vinden zijn.

xml

Legacy Member
wow, dit maakt het direct een pak onduidelijker. Ik ben voor een soort prefix (zoals ik reeds zei in m'n vorige post), maar enkel voor het id hoor. Dit is echt :crazy: nu. Ieder z'n systeempje wss. :)

WHiSPy

Legacy Member
- Als ge die kolom 'n alias geeft (select veld as naam from table), dan ga je dat probleem dus niet krijgen.
- Een associatieve array gebruikt 'n string als index. Wat jij daar hebt staan is 'n constante. (geen $ ervoor en 't is geen string)

PerfectPC

Legacy Member
`SeriOUs zei:
merci, zal me aan beide tips houden!
en ik ga je de tegenovergestelde tip geven ;)

- je mag gerust * gebruiken in een SELECT, enkel als je een zeer stricte layout van je resultatentabel nodig hebt, of als je bezig bent met 10 000-en rijen kan je beter overschakelen naar specifieke opsomming van de gewenste kolommen
- je mag ook gerust in elke tabel een primary autoincrement veld `id` gebruiken. als je een JOIN uitvoert kan je alle velden nog onderscheiden door gebruik te maken van een volledige benaming (eigenlijk gebruik je nu altijd afgekorte benamingen) vb: `tbllinks`.`id` en `tblclass`.`id` zijn zo ondubbelzinnig van elkaar te onderscheiden. (en zelfs dit is nog niet de volledige benaming, de naam van de database hoort er eigenlijk ook voor, maar dat heb je niet nodig)
- zoals Whispy zegt kan je ook gebruik maken van kolom aliassen om deze van elkaar te onderscheiden en om eventueel kolomnamen te veranderen naar de resultatentabel toe.

-> whispy: die echo is wel correct, als je var tussen " " om te echo'en staat moet (mag) je geen haakjes meer gebruiken om je element in een array te benoemen. je kan de " " voor de echo ook weglaten en wel ' ' gebruiken rond de id ;) {} rond de array gebruiken mag ook en is noodzakelijk voor het echo'en van multidimensionele arrays :) (tussen " " wel te verstaan)

PHP:
$result = mysql_query ("
  SELECT `l`.*, `c`.`class`
  FROM `tbllinks` AS `l`
  INNER JOIN `tblclass` AS `c`
  ON `l`.`classid` = `c`.`id`
") or die (mysql_error());
while ($links = mysql_fetch_array ($result)) {
   echo $links['id'];
}
PS: ik gebruik ook ALTIJD ` ` om kolommen en tabellen te benoemen, zo kan je NOOIT in de knoop geraken met verboden benamingen. dit wordt ook aangemoedigd door de MySQL ontwikkelaars.

WHiSPy

Legacy Member
PerfectPC zei:
en ik ga je de tegenovergestelde tip geven ;)
- je mag gerust * gebruiken in een SELECT, enkel als je een zeer stricte layout van je resultatentabel nodig hebt, of als je bezig bent met 10 000-en rijen kan je beter overschakelen naar specifieke opsomming van de gewenste kolommen

Enig idee wat de database-server gaat doen als je 'n select * doet? :)

PerfectPC

Legacy Member
WHiSPy zei:
Enig idee wat de database-server gaat doen als je 'n select * doet? :)
jazeker, die gaat alle records van een tabel in zn geheugen plaatsen ;) ik zeg dan ook dat je dat best niet meer doet als je werkt met tabellen die enkele 10 000 records groot zijn :) (of tabellen met een veel te hoog aantal tabellen met byteverslinde types)

als je mijn voorbeeldje bekijkt merk ja dat ik ook niet SELECT * gebruik hé

|M°B|Morbuus

Legacy Member
xml, tuurlijk, maar ppc bedoelde dat wanneer je velden data van 10000 rijen neemt dat veel meer is dan 1 kolom van 10000

WHiSPy

Legacy Member
Disa zei:
kzou het eigenlijk wel interresant vinden om men mysql-code eens 'op te tunen'.
Ge kent soms zo geen sites die hieromtrent meer info verschaffen? (buiten mysql.com dan)

- Disa

Belangrijkste tool voor het tunen van queries is nog altijd de explain plan. Zo kunt ge kijken welke operaties mysql gaat uitvoeren bij 't uitvoeren van een query. (soort join, full table scan dan wel 'n index scan, etc) Ge krijgt dan ook het gewicht van een bepaalde operatie te zien. Een full-table scan gaat bv meestal zwaarder door wegen dan een index scan, etc.

De juiste mysql-pagina hieromtrent is http://dev.mysql.com/doc/refman/5.0/en/explain.html :)
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan