https://fgheysels.github.io/
op die screen staat er idd nog geen group by in, en das de bedoeling, want die werkt toch niet zoals het moet. Tis beter voor jullie dat ik iets werkend toon, en dan vraag "hoe krijg ik van hieruit nu de laatste reactie per profiel"
[ Voor 67% gewijzigd door Buzz_Fuzz op 29-04-2004 15:44 ]
Beschrijf je probleem eens in duidelijke bewoordingen dan kunnen we je wel een paar hints geven
buit is binnen sukkel
Mijn probleem is heel simpel:
hoe krijg ik de laatste reactie per profiel
Omdat dit nogal vaag is voor buitenstaanders heb ik een screen gemaakt met de gegevens waarmee gewerkt moet worden (zie first post). Aangezien ik per profiel de laatste reactie wil, wordt dat in het voorbeeld: reactie_id 8 en 5 eruit halen
Omdat je de code niet zou moeten overtypen vanuit de screen:
1
2
3
4
5
6
7
8
| SELECT tt_userreacties.reactie_id, tt_userreacties.poster_id AS poster_id, tt_userreacties.user_id AS profiel_id, tt_userreacties.datum, u1.username AS profiel_name, u2.username AS poster_name FROM tt_userreacties LEFT JOIN phpbb_users u1 ON u1.user_id = tt_userreacties.user_id LEFT JOIN phpbb_users u2 ON u2.user_id = tt_userreacties.poster_id ORDER BY tt_userreacties.datum DESC LIMIT 0 , 10 |
Zo duidelijk genoeg?
[ Voor 2% gewijzigd door gorgi_19 op 29-04-2004 15:59 . Reden: En terug is de layout... ]
"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney
1
2
3
4
5
6
7
8
9
10
11
12
| SELECT tt_userreacties.reactie_id, tt_userreacties.poster_id AS poster_id, tt_userreacties.user_id AS profiel_id, tt_userreacties.datum, u1.username AS profiel_name, u2.username AS poster_name FROM tt_userreacties LEFT JOIN phpbb_users u1 ON u1.user_id = tt_userreacties.user_id LEFT JOIN phpbb_users u2 ON u2.user_id = tt_userreacties.poster_id GROUP BY tt_userreacties.user_id HAVING tt_userreacties.reactie_id = MAX( tt_userreacties.reactie_id ) LIMIT 0 , 10 |
Werkt niet, output is leeg
Never underestimate the power of
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| SELECT tt_userreacties.reactie_id, tt_userreacties.poster_id AS poster_id, tt_userreacties.user_id AS profiel_id, tt_userreacties.datum, u1.username AS profiel_name, u2.username AS poster_name FROM tt_userreacties ttu LEFT JOIN phpbb_users u1 ON u1.user_id = tt_userreacties.user_id LEFT JOIN phpbb_users u2 ON u2.user_id = tt_userreacties.poster_id WHERE EXISTS ( SELECT MAX( reactie_id ) FROM tt_userreacties ttu2 WHERE ttu2.profielid = ttu.profielid HAVING MAX(reactie_id) = ttu.reactie_id ) ORDER BY tt_userreacties.datum DESC LIMIT 0 , 10 |
Ik heb nu even geen mysql geinstalleerd staan hier, dus ik heb dit getest onder Oracle op een soortgelijke tabel en dat lijkt te werken.
Echter niet alle versies van MySQL ondersteunen subqueries en als dat zo is voor jouw MySQL versie dan ontkom je er vrees ik niet aan om met temptabellen of iets dergelijks te gaan werken. De binnenste query stop je dan in een temptabel en vervolgens voeg je een join op deze temptabel toe aan de buitenste query.
Hij groepeert per profiel, maar toont de kleinste reactie_id ipv de grootste.....
Dat bedoel ik ook nietBuzz_Fuzz schreef op 29 april 2004 @ 16:05:
You mean this?
PHP:
1 2 3 4 5 6 7 8 9 10 11 12 SELECT tt_userreacties.reactie_id, tt_userreacties.poster_id AS poster_id, tt_userreacties.user_id AS profiel_id, tt_userreacties.datum, u1.username AS profiel_name, u2.username AS poster_name FROM tt_userreacties LEFT JOIN phpbb_users u1 ON u1.user_id = tt_userreacties.user_id LEFT JOIN phpbb_users u2 ON u2.user_id = tt_userreacties.poster_id GROUP BY tt_userreacties.user_id HAVING tt_userreacties.reactie_id = MAX( tt_userreacties.reactie_id ) LIMIT 0 , 10
Werkt niet, output is leeg
SELECT MAX(tt_userreacties.reacti_id) bedoelde ik wel.
Hierna zul je nog moeten groeperen (je GROUP BY
"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| SELECT max(tt_userreactiesdatum) as datum tt_userreacties.reactie_id, tt_userreacties.poster_id, tt_userreacties.user_id AS profiel_id, u1.username AS profiel_name, u2.username AS poster_name FROM tt_userreacties LEFT JOIN phpbb_users u1 ON u1.user_id = tt_userreacties.user_id LEFT JOIN phpbb_users u2 ON u2.user_id = tt_userreacties.poster_id GROUP BY (profiel_id) |
Als ik goed begrijp wat jij bedoelt id dit de oplossing.
Kun je de querie met temptables eens laten zien?Buzz_Fuzz schreef op 29 april 2004 @ 17:03:
nee beiden gaan niet....
Hij groepeert per profiel, maar toont de kleinste reactie_id ipv de grootste.....
Neen, dit toont opnieuw de KLEINSTE reactie_id per profiel_id, ik heb de grootste (dus de meest recente) nodig. Die group by maakt van de rijen met dezelfde profiel_id, 1 rij, en dit doet hij door de rij met de kleinste reactie_id uit de group te halen. Tis de GROOTSTEN diek moe hebben....beetle71 schreef op 29 april 2004 @ 17:25:
PHP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 SELECT max(tt_userreactiesdatum) as datum tt_userreacties.reactie_id, tt_userreacties.poster_id, tt_userreacties.user_id AS profiel_id, u1.username AS profiel_name, u2.username AS poster_name FROM tt_userreacties LEFT JOIN phpbb_users u1 ON u1.user_id = tt_userreacties.user_id LEFT JOIN phpbb_users u2 ON u2.user_id = tt_userreacties.poster_id GROUP BY (profiel_id)
Als ik goed begrijp wat jij bedoelt id dit de oplossing.
Wat bedoel je met temptables?
[ Voor 15% gewijzigd door Buzz_Fuzz op 29-04-2004 17:58 ]
Verwijderd
uwe MAX():
1
2
3
4
5
6
7
8
9
10
11
12
| SELECT max( tt_userreacties.reactie_id ) AS max_reactie_id, tt_userreacties.reactie_id, tt_userreacties.poster_id, tt_userreacties.user_id AS profiel_id, u1.username AS profiel_name, u2.username AS poster_name FROM tt_userreacties LEFT JOIN phpbb_users u1 ON u1.user_id = tt_userreacties.user_id LEFT JOIN phpbb_users u2 ON u2.user_id = tt_userreacties.poster_id GROUP BY ( profiel_id ) ORDER BY datum DESC LIMIT 0 , 30 |
output:
http://studweb.hogent.be/~031129sd/query2.jpg
hij blijft de KLEINSTE reactie_id pakken. Alsek daar ne HAVING reactie_id = MAX(reactie_id) bijsmijt, geeft hij maar 1 record terug, dat met de hoogste reactie_id (10)
@ HereIam: wie zei dat ik wil deleten?????
[ Voor 5% gewijzigd door Buzz_Fuzz op 29-04-2004 18:18 ]
Als je versie van MySQL dat niet kan dan kun je bijvoorbeeld denken aan het bijhouden van de laatste reactie per profiel bij invoer van een nieuwe reactie dmv. een extra veld.
Who is John Galt?
Kheb enkele topics gevonden die ook met een dergelijk probleem zitten (group by die de kleinste reactie_id eruit haalt ipv de grootste):
[rml][ MySQL] Ordenen op datum, maar ook GROUP BY gebruiken[/rml]
[rml][ SQL] eerst order dan group[/rml]
en bij hen lukt het wél door
"max( tt_userreacties.datum ) AS max_datum"
en
"GROUP BY (tt_userreacties.user_id) ORDER BY max_datum DESC "
te gebruiken, bij mij blijft hij de kleinste tonen ...:s
[ Voor 11% gewijzigd door Buzz_Fuzz op 29-04-2004 18:56 ]
Ten eerste, zo te zien krijg je het resultaat zoals het hoort, immers max_reactie_id bevat de hoogste waarde, nietwaar? Deze kolom kun je dus gebruiken.
De ordening zorgt alleen ende slechts voor weergave. Dit heeft dus geen invloed op de uitslag van de query.
De having zoals ik die in mijn query gebruikte werkt alleen in de subquery, daarbij gebruikte ik namelijk in de binnenste query een veld uit de buitenste query. Een having in jouw geval zonder subquery heeft zeker niet het gewenste resultaat.
Denk je dat je nu verder kunt?
Oh ja, ripexx gaf trouwens al aan dat in "echt" SQL jouw query niet zou mogen werken, omdat een group by alle niet "aggregate" functie kolommen die bij SELECT staat zou horen te noemen. Blijkbaar heeft MySQL een leuke uitbreiding op de standaard gedaan, maar dit kan dus wel tot onvoorspelbaar gedrag leiden, zoals jij nu zelf tegenkomt.
[ Voor 23% gewijzigd door bigbeng op 30-04-2004 00:28 ]
Ik ga even iets anders proberen...
Verwijderd
Dan heb ik je verkeerd begrepen met 'eruit halen' zoals je in je startpost schreefBuzz_Fuzz schreef op 29 april 2004 @ 18:16:
@ HereIam: wie zei dat ik wil deleten?????
Anders zul je vrees ik toch met een temporary tabel moeten werken, dit is volgens mij wel mogelijk ook met jouw versie van MySQL.
Als ik de query uit je TS zie, en de waarden die daaruit komen, zou de query zoals ik hem eerder gaf toch echt alleen maar reactie_id 8 & 5 terug moeten geven. Maar volgens jou komt dat er niet uit. Ik ben heel benieuwd wat er dan wel uit komt. Kun je dat laten zien?
Misschien dat we dan ook beter begrijpen wat er nou nog niet goed gaat.
Verwijderd
SELECT reactieid, profiel_name FROM reactie
GROUP BY profiel_name
HAVING datum = MAX(datum)
Hierbij groupeer je per profiel_name elke datum die gelijk is aan de MAX(datum) per groep. Je zult de query alleen wel even moeten aanpassen (joins e.d. toevoegen).
Volgens mij ben je dan al klaar met deze code:
1
2
3
4
5
6
| SELECT reactie_id, MAX(reactie_id) FROM Tabel GROUP BY profiel_id |
Wil je ook zaken als de poster en de datum van de laatste reactie erbij, dan moet je inderdaad rijen gaan selecteren zoals firestorm2004 dat ook doet:
1
2
3
4
5
6
7
8
| SELECT profiel_name, reactie_id, poster_id, datum FROM Tabel GROUP BY profiel_id HAVING reactie_id=MAX(reactie_id); |
Verder heb je, denk ik, geen joins nodig, behalve misschien om de tekst van de reactie te vinden (dat komt in het verhaal van de topic starter helemaal niet voor).
Overigens vind ik het wel vreemd dat je allerlei informatie over de reactie (zoals degene die 'm geplaatst heeft, en de datum waarop 'ie geplaatst is) in deze tabel staat, maar de rest van de informatie (de inhoud, om te beginnen) blijkbaar ergens anders staat. Het lijkt me veel logischer om alle reactie-inforamtie in een enkele tabel te stoppen.
[ Voor 25% gewijzigd door Soultaker op 01-05-2004 22:49 ]
Idd, uw query geeft niet het gewenste resultaat.beetle71 schreef op 01 mei 2004 @ 12:36:
Mmmmh. Ik snap het niet helemaal meer.
Als ik de query uit je TS zie, en de waarden die daaruit komen, zou de query zoals ik hem eerder gaf toch echt alleen maar reactie_id 8 & 5 terug moeten geven. Maar volgens jou komt dat er niet uit. Ik ben heel benieuwd wat er dan wel uit komt. Kun je dat laten zien?
Misschien dat we dan ook beter begrijpen wat er nou nog niet goed gaat.
Ik heb uw query nog eens laten lopen, maar lichtjes aangepast. Kheb er MAX(reactie_id) bijgezet, om duidelijk te maken wat de hoogste reactie_id per profiel is (en dus welke rijen hij eigenlijk zou moeten ophalen). Als ge echter naar de reactie_id kolom kijkt, zie je dat hij toch niet de hoogste, maar de kleinste reactie_id per profiel ophaalt.
13 <=> 6
5 <=> 1
...
http://studweb.hogent.be/~031129sd/query3.jpg
Die joins dienen om de username van de poster, en van de profieleigenaar op te halen uit een andere (phpBB) tabel.Soultaker schreef op 01 mei 2004 @ 22:47:
Verder heb je, denk ik, geen joins nodig, behalve misschien om de tekst van de reactie te vinden (dat komt in het verhaal van de topic starter helemaal niet voor).
Lol, dat is omdat ik een overzichts tabel op men site wil vormen die een overzicht geeft van de 10 profielen waarop het laatste een reactie werd geplaatst. Dan moet ik toch niet te hele reactie zelf fetchenSoultaker schreef op 01 mei 2004 @ 22:47:
Overigens vind ik het wel vreemd dat je allerlei informatie over de reactie (zoals degene die 'm geplaatst heeft, en de datum waarop 'ie geplaatst is) in deze tabel staat, maar de rest van de informatie (de inhoud, om te beginnen) blijkbaar ergens anders staat. Het lijkt me veel logischer om alle reactie-inforamtie in een enkele tabel te stoppen.
Uw voorstel geeft echter ook geen gewenst resultaat:
http://studweb.hogent.be/~031129sd/query4.jpg
Ik heb het nu al op een andere manier kunnen oplossen, maar dan werk ik met 2 query's:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| $string = ""; $blah = mysql_query("SELECT MAX(reactie_id) AS maxreact FROM tt_userreacties GROUP BY user_id ORDER BY reactie DESC LIMIT 0,10"); while($blahblah = mysql_fetch_array($blah)) { $string .= "tt_userreacties.reactie_id = ".$blahblah['maxreact']." OR "; } $string = substr($string,0,-4); $SQL_posts = "SELECT tt_userreacties.poster_id AS poster_id, tt_userreacties.user_id AS profiel_id, tt_userreacties.datum, u1.username AS profiel_name, u2.username AS poster_name FROM tt_userreacties LEFT JOIN phpbb_users u1 ON u1.user_id = tt_userreacties.user_id LEFT JOIN phpbb_users u2 ON u2.user_id = tt_userreacties.poster_id WHERE ".$string." ORDER BY tt_userreacties.reactie_id DESC"; |
Het resultaat kunt ge hier zien:
http://www.teletet.org
beke naar beneden scrollen: "Nieuwe reacties op volgende profielen ::.. "
[ Voor 8% gewijzigd door Buzz_Fuzz op 02-05-2004 01:48 ]
Waarom doe je nu opeens die MAX(tt_userreacties.datum) erbij? Ik ben bang dat je dan juist meer aggregeert dan nodig is. Haal die MAX() er eens uit?
Twee queries is ook geen ramp, denk ik, als is het wel jammer dat je al die tijdelijke resultaten in een grote string moet gaan stoppen. Als het om veel rijen gaat, is het gebruik van een temporary table waarschijnlijk een stuk efficiënter.
maar zonder die max(datum) maakt het geen verschil
tzijn maximum 10 rijen dietie maar moe tonen (LIMIT 0,10), dus die string is zo geen probleem.
[ Voor 4% gewijzigd door Buzz_Fuzz op 02-05-2004 02:38 ]
2x MAX(...) in een query gaat NIET werken!Buzz_Fuzz schreef op 02 mei 2004 @ 01:45:
[...]
Idd, uw query geeft niet het gewenste resultaat.
Ik heb uw query nog eens laten lopen, maar lichtjes aangepast. Kheb er MAX(reactie_id) bijgezet, om duidelijk te maken wat de hoogste reactie_id per profiel is (en dus welke rijen hij eigenlijk zou moeten ophalen). Als ge echter naar de reactie_id kolom kijkt, zie je dat hij toch niet de hoogste, maar de kleinste reactie_id per profiel ophaalt.
13 <=> 6
5 <=> 1
...
http://studweb.hogent.be/~031129sd/query3.jpg
Ik heb het nu al op een andere manier kunnen oplossen, maar dan werk ik met 2 query's:
[SNIP]
heb ik al gezegd.................
uw query op de vorige pagina, geeft zowel met enkel max(datum), als met max(datum) én max(reactie_id) hetzelfde, verkeerde resultaat!!!! 1 of 2 MAX'en, dat maakt niet uit in uw query.
