PHP, mySQL, Hämta data från 2 tabeller

Permalänk
Medlem

PHP, mySQL, Hämta data från 2 tabeller

Jag försöker hämta ut information från 2 tabeller i min databas

users och guestbook

users tabellen ser ut såhär: userID, username, password, email
guestbook ser ut såhär: gbID, userID, toID, text, date

userIDt hämtar jag med hjälp av $_GET['userID']

Här är min kod jag använder just nu

SELECT u1.*, g.text AS entry_text, g.date AS guestbook_date, u2.userID AS from_userID, u2.username AS from_username FROM users AS u1 LEFT JOIN guestbook AS g ON u1.userID = g.toID LEFT JOIN users AS u2 ON g.userID = u2.userID WHERE u1.userID = :userId ORDER BY g.date DESC;

Den här koden fungerar-ISH, han hämtar alla resultat förutom 1. Körde denna kod genom PHPMyAdmin och fick detta resultatet

Showing rows 0 - 9 (10 total, Query took 0.0037 seconds.) SELECT u1.*, g.text AS entry_text, g.date AS guestbook_date, u2.userID AS from_userID, u2.username AS from_username FROM users AS u1 LEFT JOIN guestbook AS g ON u1.userID = g.toID LEFT JOIN users AS u2 ON g.userID = u2.userID WHERE u1.userID = 15 ORDER BY g.date DESC;

Som ni ser så hämtar han bara ut 9 av 10 totalt så en saknas.

Här är datan som kom ut

userID username email text(entry_text) date(guestbook_date) toID userID(from_userID), username(from_username) 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12

Så slutsatsen, den ska hämta ut en användare från databasen alltså den profilen du besöker. Sen ska den plocka ut alla inlägg från guestbook med det toID:t och visa dessa och även plocka ut användarnamnet för den som skickar gästboksinlägget.

Permalänk
Skrivet av ThLoser:

Jag försöker hämta ut information från 2 tabeller i min databas

users och guestbook

users tabellen ser ut såhär: userID, username, password, email
guestbook ser ut såhär: gbID, userID, toID, text, date

userIDt hämtar jag med hjälp av $_GET['userID']

Här är min kod jag använder just nu

SELECT u1.*, g.text AS entry_text, g.date AS guestbook_date, u2.userID AS from_userID, u2.username AS from_username FROM users AS u1 LEFT JOIN guestbook AS g ON u1.userID = g.toID LEFT JOIN users AS u2 ON g.userID = u2.userID WHERE u1.userID = :userId ORDER BY g.date DESC;

Den här koden fungerar-ISH, han hämtar alla resultat förutom 1. Körde denna kod genom PHPMyAdmin och fick detta resultatet

Showing rows 0 - 9 (10 total, Query took 0.0037 seconds.) SELECT u1.*, g.text AS entry_text, g.date AS guestbook_date, u2.userID AS from_userID, u2.username AS from_username FROM users AS u1 LEFT JOIN guestbook AS g ON u1.userID = g.toID LEFT JOIN users AS u2 ON g.userID = u2.userID WHERE u1.userID = 15 ORDER BY g.date DESC;

Som ni ser så hämtar han bara ut 9 av 10 totalt så en saknas.

Här är datan som kom ut

userID username email text(entry_text) date(guestbook_date) toID userID(from_userID), username(from_username) 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12 15 0 user15 user15@example.com This aint working1 2023-12-29 19:12:18 12 user12

Så slutsatsen, den ska hämta ut en användare från databasen alltså den profilen du besöker. Sen ska den plocka ut alla inlägg från guestbook med det toID:t och visa dessa och även plocka ut användarnamnet för den som skickar gästboksinlägget.

Vad jag kan se "0-9 rows (10 total...)" så bör det betyda 10 rader som hämtats? När jag räknar så blir det också 10 rader som börjar på "15 0 user15 ...". Jag förstår dock inte varför det finns både "user15" och "user12" per rad? 🤔 Har det något med "toID" vilket verkar indikera på att varje gästboksinlägg är avsedd för vems gästbok inlägget är skrivet i?

Mvh,
WKL.

Visa signatur

"Den säkraste koden är den som aldrig skrivs"
"Visste du förresten att det är ett mångmiljardbolag?"
"Jag lever inte för att koda utan kodar för att sen kunna leva"

Permalänk
Medlem

Hej! Det står att den visar 0-9 10 rader totalt.. Och den 10e raden finns när man kör i phpmyadmin men den är ej synlig. Kan ta print om du vill

Permalänk
Medlem

På den här så är det 10 stycken userID som är markerade men bara 9 stycken fromID som är markerade om man kollar på den svarta bordern som går runt vid userID och from_userID

Permalänk
Medlem
Skrivet av ThLoser:

Hej! Det står att den visar 0-9 10 rader totalt.. Och den 10e raden finns när man kör i phpmyadmin men den är ej synlig. Kan ta print om du vill

I programmering används nästan alltid nollindexering, d.v.s. första index är 0. 0-9 betyder att du har samtliga tio rader i ditt resultat.

Visa signatur

AMD Ryzen 7 1700X 3.8 GHz 20MB | ASUS PRIME X370-PRO | MSI GeForce GTX 1080 Gaming X 8GB | G.Skill 16GB DDR4 3200 MHz CL14 Flare X | Corsair RM650x 650W

Permalänk
Medlem

Jag tror det är något galet i dina left joins eftersom du gör 2 stycken. Du joinar ju först gästboken på användaren, och sen joinar du användarid på gästbokens användarens igen.

I mina ögon borde det bara var en left join eftersom det enbart är 2 tabeller.

LEFT JOIN
guestbook AS g ON u1.userID = g.toID
LEFT JOIN
users AS u2 ON g.userID = u2.userID

Visa signatur

Ei bor i stockholm och tar inget ansvar för allt som han säger
7900, 64 gig ram, radeon r290
Solna arbetscenter

Permalänk
Medlem
Skrivet av noMad17:

I programmering används nästan alltid nollindexering, d.v.s. första index är 0. 0-9 betyder att du har samtliga tio rader i ditt resultat.

Kolla på bilden jag skickade på phpmyadmin så ser du att jag har har fått alla 10 resultat eller ja alla 10 fromID

Så ja den hämtar alla userID men inte den gästboksraden eller vad man ska säga.

Permalänk
Medlem
Skrivet av Ei:

Jag tror det är något galet i dina left joins eftersom du gör 2 stycken. Du joinar ju först gästboken på användaren, och sen joinar du användarid på gästbokens användarens igen.

I mina ögon borde det bara var en left join eftersom det enbart är 2 tabeller.

LEFT JOIN
guestbook AS g ON u1.userID = g.toID
LEFT JOIN
users AS u2 ON g.userID = u2.userID

Den anledningen är som så att jag hämtar användarIDT med profile.php?userID=1

Och då får du fram userID 1 på profilen plus hans inlägg.. Sen från guestbook hade jag bara användaridt på den som skickade alltså behövde jag sätta ett nickname på han, där av kommer den andra left join in så jag kan ta ut ett användarnamn på den som har skickat gästboksinlägget

Permalänk
Medlem
Skrivet av Ei:

Jag tror det är något galet i dina left joins eftersom du gör 2 stycken.

Frågan (och resultatet) ser korrekt ut tycker jag, men den är mycket riktigt förvirrande skriven. Den hämtar ut redundant information på varje rad om vem gästboksinlägget är riktad till. Kanske görs det i debugsyfte?

Personligen föredrar jag implicita joins:
select t1.a, t2.b from t1, t2 where t1.c=t2.b and t2.c = myparam

Förutom när man behöver outer joins, men det är ganska sällan. I alla fall Oracle har en kortsyntax även för outer joins om jag inte minns fel.

Permalänk
Medlem
Skrivet av KAD:

Frågan (och resultatet) ser korrekt ut tycker jag, men den är mycket riktigt förvirrande skriven. Den hämtar ut redundant information på varje rad om vem gästboksinlägget är riktad till. Kanske görs det i debugsyfte?

Personligen föredrar jag implicita joins:
select t1.a, t2.b from t1, t2 where t1.c=t2.b and t2.c = myparam

Förutom när man behöver outer joins, men det är ganska sällan. I alla fall Oracle har en kortsyntax även för outer joins om jag inte minns fel.

Den hämtar ut all användarinformation från users med userID med hjälp av $_GET['userID']

Sen joinar den tabellen guestbook och hämtar alla gästboksinlägg toID = $_GET['userID']
Så som förnamn, efternamn, email osv osv osv

Där och då fick jag ett problem att gästboksdelen sparar
userID = Den som postat inlägget
text = texten som han skrivit
date = Datumet som det är postat
toID = $_GET['userID']

Problemet är att jag bara har ett användarID på profilen som postat inlägget och behövde ett användarnamn..
Frågan är då om det blir smidigare att ta ut alla inlägg osv och göra en funktion för att hämta ut användarnamnet istället för att joina tabellen för att få ut det.

Permalänk
Medlem

Gjorde en fiddle på detta https://www.db-fiddle.com/f/4xartd2hGXQZHuNmqgSiMW/0 och jag får INTE samma fel på den som jag får i min utan på fiddle får jag fram ALLA resultat. Fattar inte vad det är jag missar.

Efter lite forskande och testande kom jag fram till att problemet ligger inte i queryn utan det ligger i PHP koden som behandlar datan..

<?php $thisId = intval($_GET['userID']); $sql = " SELECT u1.*, g.text AS entry_text, g.date AS guestbook_date, u2.userID AS from_userID, u2.username AS from_username FROM users AS u1 LEFT JOIN guestbook AS g ON u1.userID = g.toID INNER JOIN users AS u2 ON u2.userID = g.userID WHERE u1.userID = :userId ORDER BY g.date DESC;"; // Bind the parameters $stmt = $db->prepare($sql); $stmt->bindParam(':userId', $thisId, PDO::PARAM_INT); // Execute the query $stmt->execute(); $userData = $db->fetchAssoc($stmt); if (empty($userData)) { echo '<div class="column"><h2><span class="blue">PLAY.</span> Profil ej hittad</h2><div class="alert-error">Användaren du försökte hitta finns ej i vårat system...</div></div>'; } else { echo '<div class="column column-60">'; echo '<h2><span class="radius"><span class="blue">PLAY.</span> Profil</span></h2>'; echo '<div class="UserTitle">'.$userData['username'].' </div>'; echo '<div class="Content">'; echo '<div class="ImageBox"><img src="/img/users/1.png"></div>'; echo '</div>'; echo '</div>'; echo '<div class="column column-40">'; echo '<h2><span class="radius"><span class="blue">PLAY.</span> Gästbok</span></h2>'; if (empty($userData['entry_text'])) { echo '<div class="alert-error">Tyvärr så har inte '.$userData['username'].' några gästboksinlägg :(</div>'; } else { echo '<table cellspacing="0" cellpadding="0" class="GuestBook">'; while ($row = $db->fetchAssoc($stmt)) { var_dump($row); echo '<br><br>'; echo '<tr><td width="60" valign="top"><div class="ImageBox"><img src="/img/users/1.png"></div></td><td valign="top"><div class="Title"><a href="/user/'.$row['from_userID'].'">'.$row['from_username'].'</a> - '.date('Y-m-d H:i', strtotime($row['guestbook_date'])).'</div><div class="Content">'.$row['entry_text'].'</div></td></tr>'; } echo '</table>'; echo '<div class="pagination"></div>'; } if ($userID != $thisId) { echo '<form method="post"><input type="hidden" name="toID" value="'.$thisId.'"><textarea name="text" placeholder="Skriv ett meddelande..."></textarea><input type="submit" name="addGB" value="Skicka" class="btn-blue"></form>'; } echo '</div>'; } $db->close(); ?>

Där while rowen ligger nu saknar jag en post, men lägger jag den före $userData variabeln så får jag ut all data.

Permalänk
Medlem

Nu får ni rätta mig om jag har fel, men du är korrekt. Jag tycket det ser ut som att du redan får ut första raden när du kör
$userData = $db->fetchAssoc($stmt);
Gissar att du listat ut det redan.

Så när du sen kör $row = $db->fetchAssoc($stmt)) så är du inne på rad2 därav att rad1 är förlorad

Visa signatur

Ei bor i stockholm och tar inget ansvar för allt som han säger
7900, 64 gig ram, radeon r290
Solna arbetscenter

Permalänk
Medlem
Skrivet av Ei:

Nu får ni rätta mig om jag har fel, men du är korrekt. Jag tycket det ser ut som att du redan får ut första raden när du kör
$userData = $db->fetchAssoc($stmt);
Gissar att du listat ut det redan.

Så när du sen kör $row = $db->fetchAssoc($stmt)) så är du inne på rad2 därav att rad1 är förlorad

Precis! Så det hela slutade med att jag gjorde en PHP klass istället och tog ut alla gästboksinlägg där igenom istället!

Permalänk
Medlem

Första steget med SQL är väl ändå alltid att köra SQL frågan i nått annat verktyg? Som t.ex. Management studio (för Microsft SQL server)

Då märker man fort om felet ligger i frågan eller i nått däromkring

Men skönt att det löste si g:)

Visa signatur

5700x3D | RTX 3080 | 2 TB M.2 | 32 GB RAM

Permalänk
Medlem
Skrivet av FX9:

Första steget med SQL är väl ändå alltid att köra SQL frågan i nått annat verktyg? Som t.ex. Management studio (för Microsft SQL server)

Då märker man fort om felet ligger i frågan eller i nått däromkring

Men skönt att det löste si g:)

Har typ aldrig använt mig av left join och sånt så aldrig haft såna problem innan, men köra frågan innan gjorde stor skillnad kan jag säga dig så ja man fick ju lära sig något xD