MySQL - Hvordan hente data fra to tabeller?

Mr Vest

Sjefen over alle sjefer!
Jeg er i en sitrasjon hvor jeg trenger å hente ut data fra to forkjellige tabeller. Saken er at jeg med spørring nr 1 får ut 20 forkjellige brukernavn, og jeg skal med disse 20 brukernavnene hente ut et felt tilknyttet de forkjellige brukernavnene i en annen tabell.

Det jeg har forsøkt av kode finner vi under, men i koden der viser det seg at $getvideoprofilestatuses ikke har lyst og hente ut riktige verdier fra databasen. Den henter f.eks 20 helt like verdier som kun hører til ett av brukernavnene.

Kode 1 jeg har forsøkt skrev:
$hentbrukernavnene=mysql_query("select username from users where imageorvideo = 'video' order by rand() LIMIT 20",$c);
while($brukernavn=mysql_fetch_array($hentbrukernavnene))
{
$getvideoprofilestatuses=mysql_query("select statusoppdatering from statusupdates where userid = '$brukernavn[username]' order by id desc LIMIT 20",$c);
while($status=mysql_fetch_array($getvideoprofilestatuses))
{
echo'
<li>Brukernavn: '.$brukernavn[username].' - '.$status[statusoppdatering].'</li>
';
}
}

Jeg leste litt om en CONCAT-greie som ser ut til å kunne hente ut informasjon fra flere tabeller i databasen, men jeg forstår ikke helt hvordan den funker når jeg ser på eksemplene. Er jeg på rett vei når jeg tenker CONCAT? (evt. konekatt som jeg tenker hver gang jeg hører det ordet?)

På forhånd, takk så mye for hjelpen her altså. :)
 

Nextri

Rebel
SELECT username, statusoppdatering FROM users LEFT JOIN statusupdates ON users.id = statusupdates.userid ORDER BY rand(), statusupdates.id DESC LIMIT 20

noe sånt ish..

LEFT JOIN er iallefall tingen.
 

Mr Vest

Sjefen over alle sjefer!
Nå har jeg sjekket ut LEFT JOIN og noe som visstnok heter ON som man bruker i samme spørring mot databasen. Det jeg har forstått hittil er at en spørring ser slik ut:

Kode:
SELECT tabell1.felt-i-tabell-1, tabell2.felt-i-tabell-2 FROM tabell2 LEFT JOIN tabell1 ON tabell2.felt = tabell1.felt WHERE users.imageorvideo = 'video' LIMIT 20

Det som skjer i denne spørringen er at ON tabell2.felt = tabell1.felt er disse to som blir sammenlignet med hverandre og som blir hentet ut dersom de er like. Om noen av dere dyktige kodere skjønner koden der - evt har en alternativ kode ville jeg satt pris på hva jeg kan gjøre i min situasjon.

Jeg er nemlig ute etter akkurat denne effekten jeg får med spørringen over, men jeg vil ikke at samme verdi fra tabell2.felt skal hentes mer enn 1 gang selv om verdien gjentar seg flere ganger i forkjellige rader. Jeg regnet med at løsninga jeg fant her skulle kunne løse dette, men jeg vet ikke hvor jeg evt skulle lagt inn "distinct" i spørringen over. Any ideas?
 

Nextri

Rebel
Vet ikke helt hvordan tabellene dine ser ut. men jeg ville gjort noe sånt:
Kode:
SELECT username ,statusoppdatering 
FROM statusupdates
LEFT JOIN users ON users.id = statusupdates.user_id
GROUP BY statusupdates.user_id
ORDER BY statusupdates.id DESC
LIMIT 20
for å få de 20 siste statusoppdateringene.

Men vil anbefale deg å ta en titt på cakephp.org som er et php rammeverk.
Du vil da faktisk slippe å kunne særlig mye SQL i det hele tatt. Rammeverket generer spørringene for deg. Tar litt tid å sette seg inn i. Men du sparer ufattelig mye tid under utviklingen, når du først har skjønnt basics.

Spesielt denne tutorialen for å lage en blog, er veldig enkel og lærerik: Blog :: Tutorials & Examples :: The Manual :: 1.2 Collection :: The Cookbook
 

Mr Vest

Sjefen over alle sjefer!
Takk skal du ha. Etter å ha søkt som en gal siden jeg startet denne tråden og før det også har jeg nå endelig funnet ut at det er slik som du har gjort man setter en oversiktlig query inn i et diskusjonsforum. Hehe.

Derimot, så må jeg faktisk mase litt til. Det som er greia er nemlig at spørringen skal KUN hente ut informasjon DERSOM et felt som heter IMAGEORVIDEO i Users er satt til VIDEO. Hva kan jeg legge inn i spørringen over for at det skal gå seg til? Jeg forsøkte med WHERE IMAGEORVIDEO = 'video' rett over GROUP BY, men uten hell. Ingen feilmelding, men heller ikke et riktig resultat.

=
Jeg har akkurat lastet ned PHPkake og skal sjekke den ut. Takk for tips om den. Skal også gå gjennom denne guiden du foreslår for og se om jeg har fått med meg det mest grunnleggende, men det blir nok ikke før jeg har fått en god natt med søvn. :)
 

Yngve Larsen

E-commerce ekspert
SELECT username ,statusoppdatering
FROM statusupdates
LEFT JOIN users ON users.id = statusupdates.user_id
WHERE users.imageorvideo = 'video'
GROUP BY statusupdates.user_id
ORDER BY statusupdates.id DESC
LIMIT 20

Anbefaler deg å skrive og test spørringene i f.eks Navicat eller phpmyadmin, da er det lettere å se feil/justere.
 

Mr Vest

Sjefen over alle sjefer!
Takk skal du ha Yngve. Den spørringen ser ut til å gjøre jobben, og leverer kun tilbake det den skal levere. Flottings! Men en ting til - Den gjør noe rart med:

ORDER BY statusupdates.id DESC...

Den henter ikke ut siste rad men den første den finner. Jeg forsøkte å ta bort DESC men med samme resultat. Veldig rart syns jeg. Noen tanker om hva som er galt?

Takk for tips om og kjøre spørringene i Phpmyadmin. Det tenkte jeg ikke på at jeg kunne gjøre. Nå slipper jeg kanksje attpåtil at Firefox kræsjer til tider. :)
 
Problemet er at statusupdates.id ikke er med i spørringen. Prøv

SELECT statusupdates.id, username, statusoppdatering
FROM statusupdates
LEFT JOIN users ON users.id = statusupdates.user_id
WHERE users.imageorvideo = 'video'
GROUP BY statusupdates.user_id
ORDER BY statusupdates.id DESC
LIMIT 20

(altså, legg til "id" på første linje)
 
Sist redigert:

Nextri

Rebel
Problemet er at statusupdates.id ikke er med i spørringen. Prøv

SELECT id, username, statusoppdatering
FROM statusupdates
LEFT JOIN users ON users.id = statusupdates.user_id
WHERE users.imageorvideo = 'video'
GROUP BY statusupdates.user_id
ORDER BY statusupdates.id DESC
LIMIT 20

(altså, legg til "id" på første linje)

Det har ikke noe å si om man har med feltet man sorterer på i select'en
 
Ikke? Det har det alltid hatt hos meg. Har jeg det ikke med, får jeg samme problem som Atle -- legger jeg det til, forsvinner feilen og rekkefølgen blir riktig igjen.
(edit2: Men ser at når jeg tester dette i phpmyadmin, viser det seg at du har helt rett. Rart. Nå ble jeg veldig usikker, for jeg har hatt dette problemet mange ganger, og alltid klart å løse det på samme måte.)

EDIT: Ser etter testing at du må endre id til statusupdates.id for at den skal virke.
 
Sist redigert:

Mr Vest

Sjefen over alle sjefer!
Jeg forsøkte faktisk å legge inn ID der oppe, men jeg legger merke til at jeg får en feilmelding slik som denne "mysql_fetch_array(): supplied argument is not a valid MySQL result resource in xxx." Det virker som at denne feilmeldinga kommer kun dersom jeg skriver inn et feltnavn i SELECT dersom dette feltet finnes i begge tabellene. Er ikke det normalt at man har ID på toppen i alle tabeller?
 

Mr Vest

Sjefen over alle sjefer!
Skjønner skjønner. Nå begynner det å ligne på noe her ja.

Grunnen til at det ikke fungerte ser ut til å være som akkurat dette med ID du sa olafmoriarty, samtidig meg selv som misforstod spørringen litt, og skrev inn feil på GROUP BY. Jeg forstår ikke helt hva GROUP BY faktisk gjør, så det er derfor jeg skrev inn feil.

Nå får jeg hvertfall akkurat det resultatet jeg ønsker. Syns dette var kjempebra. Mange dyktige folk her inne altså. Spesielt dyktig på å forstå amatørforklaringer fra slike som meg. Takk så mye. Ryktepoeng kommer etterhvert. :)

(Ser det kom to innlegg der oppe som jeg ikke fikk med meg i sted. Ok, så det er egentlig ikke nødvendig med ID. Da er det nok bare feilen jeg gjorde på GROUP BY som var feil. Veldig greit å vite.)

== And here we go again... ==

Nå kom jeg akkurat til å tenke på noe. Jeg skal forklare så godt jeg kan.

Tabell 1 - Statusupdates inneholder userid
Tabell 2 - Users inneholder username

Disse to har samme verdi. Det jeg vil er at dersom den finner flere rader som har disse to som samme verdi, da skal den hoppe over alle bortsett fra 1. (kort sagt, jeg vil kun vise 1 statusoppdatering fra hver bruker.)

Det ser ikke ut til at DISTINCT er noe jeg kan bruke her. Jeg søkte meg grønn og blå på dette i går, men jeg forstår ikke så mye av det folk skriver. Noen tanker om hvordan jeg kan få dette til?
 
Sist redigert:

Mr Vest

Sjefen over alle sjefer!
Nå blir jeg snart gal. Google er så forferdelig lite hjelpsom altså. Nå har jeg sittet her og søkt etter dette helt siden forige innlegg i denne tråden, og jeg finner absolutt ingen svar what so ever på hvordan jeg får denne til ikke å hente ut duplikatinnhold. Jeg finner mye informasjon, men ingenting en gammel mann som meg kan forstå.

Jeg bruker (bruker bare select * mens jeg prøver å forstå dette her nå) følgende spørring:

SELECT users.* ,statusupdates.*
FROM statusupdates
LEFT JOIN users ON users.username = statusupdates.userid
WHERE users.imageorvideo = 'video'
GROUP BY statusupdates.id
ORDER BY statusupdates.id DESC
LIMIT 20

Dette er 110% slik min kode ser ut nå, og den henter ut absolutt alt riktig. Det eneste er at "statusupdates" inneholder flere rader hvor "userid" er det samme som "username" i "users". Derfor kommer gjerne "Atle" som er et "username" frem 20 ganger. Har dere noen tanker om hva i alle dager jeg skal gjøre for at den skal hoppe over "Atle" dersom "Atle" allerede har kommet inn 1 antall ganger?

(Er ikke meninga og mase for mye her. Føler det er litt for mye altså, men jeg finner rett og slett ingen løsning på dette ved hjelp av ekle Google.)
 
Topp