MySQL/PHP: groeperen

Alles over programmeren en development binnen de IT-wereld
Plaats reactie
Gebruikersavatar
meon
Administrator
Administrator
Berichten: 16757
Lid geworden op: 18 feb 2003, 22:02
Twitter: meon
Locatie: Bree
Uitgedeelde bedankjes: 582 keer
Bedankt: 780 keer
Provider

Ik heb een SQL-probleempje en weet niet meteen hoe dat netjes op te lossen:
Zoals je in de screenshot ziet wil ik de nieuwsberichten groeperen per datum. In SharePoint is dat easy-peasy (zie screenshot), maar hoe los je dat manueel op?

Wat ik dus wil: maximaal X aantal artikels, gegroepeerd per datum.
Ik dacht simpelweg via group by, maar da's dus niet juist ;)
Bijlagen
groupbyproblem.gif
(10.98 KiB) 1524 keer gedownload
ubremoved_539
Deel van't meubilair
Deel van't meubilair
Berichten: 29849
Lid geworden op: 28 okt 2003, 09:17
Uitgedeelde bedankjes: 434 keer
Bedankt: 1972 keer

In Oracle kan je dit via ranking, maar ik weet niet of MySQL dat heeft.

Via TOP n zal waarschijnlijk niet lukken op een GROUP BY ?
Gebruikersavatar
meon
Administrator
Administrator
Berichten: 16757
Lid geworden op: 18 feb 2003, 22:02
Twitter: meon
Locatie: Bree
Uitgedeelde bedankjes: 582 keer
Bedankt: 780 keer
Provider

Neen dus ...
Beetle
Starter
Starter
Berichten: 5
Lid geworden op: 11 mei 2005, 17:18

mysql ondersteunt wel LIMIT

Code: Selecteer alles

select * from table where date_field = '$datum' limit 20
Dit haalt de eerste 20 resultaten op van een bepaalde datum

http://dev.mysql.com/doc/mysql/en/select.html
Laatst gewijzigd door Beetle 23 mei 2005, 17:30, in totaal 1 gewijzigd.
Gebruikersavatar
meon
Administrator
Administrator
Berichten: 16757
Lid geworden op: 18 feb 2003, 22:02
Twitter: meon
Locatie: Bree
Uitgedeelde bedankjes: 582 keer
Bedankt: 780 keer
Provider

Zo ver was ik ook :)

Ik dacht aan dit:

Code: Selecteer alles

SELECT DISTINCT `date` FROM news ORDER BY `date` DESC LIMIT 20;
Maar, dan limit hij het result en niet de bron; iets als "van welke unieke dagen zijn de voorbije 20 berichten".
Ik vrees dat ofwel de code te ingewikkeld gaat worden naar m'n goesting, ofwel het gewoon niet gaat via MySQL...
Beetle
Starter
Starter
Berichten: 5
Lid geworden op: 11 mei 2005, 17:18

Natuurlijk, daar vroeg je immers om:

DISTINCT zorgt ervoor dat je elk resultaat maar 1 keer te zien krijgt en je vraagt alleen het datumveld uit de tabel. Dan nog de LIMIT 20 en je krijgt 20 unieke datums.

Als je DISTINCT weglaat (of meer velden opvraagt), krijg je meer resultaten van dezelfde datum.

Probeer dit eens:

Code: Selecteer alles

SELECT DISCTINCT `date`, `subject` from news ORDER BY `date` LIMIT 20;
Gebruikersavatar
meon
Administrator
Administrator
Berichten: 16757
Lid geworden op: 18 feb 2003, 22:02
Twitter: meon
Locatie: Bree
Uitgedeelde bedankjes: 582 keer
Bedankt: 780 keer
Provider

In zo'n geval geldt de distinct op de combinatie date en subject en krijg ik dus dubbele data, maar da's niet de bedoeling.

Ik ga het houden bij m'n bovenstaande voorbeeld, gelimit op 5. Niet helemaal wat ik in gedachte had, maar close enough ... ;)
Beetle
Starter
Starter
Berichten: 5
Lid geworden op: 11 mei 2005, 17:18

Hmm, dan heb ik blijkbaar ergens iets verkeerd begrepen :oops:

Zoals ik het begreep wilde je van elke datum 20 berichten tonen?
Gebruikersavatar
meon
Administrator
Administrator
Berichten: 16757
Lid geworden op: 18 feb 2003, 22:02
Twitter: meon
Locatie: Bree
Uitgedeelde bedankjes: 582 keer
Bedankt: 780 keer
Provider

Nee, ik wil 20 berichten tonen, en die groeperen per datum, dus 20 berichten in totaal.
Lukse
Premium Member
Premium Member
Berichten: 662
Lid geworden op: 28 okt 2003, 20:51

meon schreef:Nee, ik wil 20 berichten tonen, en die groeperen per datum, dus 20 berichten in totaal.
Wat is er dan mis met:

Code: Selecteer alles

SELECT subject, date FROM news ORDER BY date DESC LIMIT 20
Gebruikersavatar
meon
Administrator
Administrator
Berichten: 16757
Lid geworden op: 18 feb 2003, 22:02
Twitter: meon
Locatie: Bree
Uitgedeelde bedankjes: 582 keer
Bedankt: 780 keer
Provider

Tabel:

Code: Selecteer alles

+------------------------+------------------------+
| date                        | Titel                        |
+------------------------+------------------------+
| 2005-05-20              | Bomen en planten    |
| 2005-05-20              | Takkenwallen          |
| 2005-05-21              | Schijvenpaden         |
| 2005-05-22              | Tuinieren                |
| 2005-05-22              | Appelbomen            |
+------------------------+------------------------+
SQL: SELECT DISTINCT date, titel FROM news ORDER BY date DESC LIMIT 2;
-> retourneert
2005-05-22, Appelbomen
2005-05-22, Tuinieren

En in welke zin is dit nu gegroepeerd (wat m'n oorspronkelijke vraag was)?
Stino
Plus Member
Plus Member
Berichten: 163
Lid geworden op: 03 jan 2004, 13:49

Ik begrijp niet juist wat je bedoeld meon, maar misschien ben je hier iets mee:

Code: Selecteer alles

SELECT DISTINCT date, (SELECT title FROM news WHERE news.title = news2.title AND news.date = news2.date) AS title FROM news news2 ORDER BY date DESC LIMIT 5;
23/5/2005 title9
23/5/2005 title8
22/5/2005 title7
21/5/2005 title6
20/5/2005 title5

Code: Selecteer alles

SELECT date, title FROM news GROUP BY date, title ORDER BY date DESC LIMIT 5;
23/5/2005 title8
23/5/2005 title9
22/5/2005 title7
21/5/2005 title6
20/5/2005 title5
Gebruikersavatar
meon
Administrator
Administrator
Berichten: 16757
Lid geworden op: 18 feb 2003, 22:02
Twitter: meon
Locatie: Bree
Uitgedeelde bedankjes: 582 keer
Bedankt: 780 keer
Provider

Dat zal onder MySQL 4 werken, maar niet onder 3, die ondersteunt geen subqueries ... Maar ik denk dat ik versie 4 heb draaien. Morgen proberen.

Maar dan nog, ik wil gewoon een identiek resultaat als dat uit het screenshot, wat zowieso meerdere queries zijn, maar de vraag is een beetje hoe die netjes te loopen ;)
Beetle
Starter
Starter
Berichten: 5
Lid geworden op: 11 mei 2005, 17:18

meon schreef: SQL: SELECT DISTINCT date, titel FROM news ORDER BY date DESC LIMIT 2;
-> retourneert
2005-05-22, Appelbomen
2005-05-22, Tuinieren

En in welke zin is dit nu gegroepeerd (wat m'n oorspronkelijke vraag was)?
Gesorteerd op datum (aflopend) en de DISTINCT zorgt ervoor dat elk paar (datum, titel) maar 1 keer teruggegeven wordt. Als er 2 keer de combinatie "2005-05-22, Tuinieren" in de tabel zat, zou die toch maar 1 keer in de resultset zitten.
Gebruikersavatar
meon
Administrator
Administrator
Berichten: 16757
Lid geworden op: 18 feb 2003, 22:02
Twitter: meon
Locatie: Bree
Uitgedeelde bedankjes: 582 keer
Bedankt: 780 keer
Provider

Dat zeg ik toch, dat is niet m'n bedoeling eh :)
Maar goed, ik heb een oplossing, waar ik voorlopig tevreden van ben ...
Lukse
Premium Member
Premium Member
Berichten: 662
Lid geworden op: 28 okt 2003, 20:51

meon schreef:Maar dan nog, ik wil gewoon een identiek resultaat als dat uit het screenshot, wat zowieso meerdere queries zijn, maar de vraag is een beetje hoe die netjes te loopen ;)
Je haalt met 1 query alles records op.
Die groeperen is toch gemakkelijk met php te doen?
Gebruikersavatar
meon
Administrator
Administrator
Berichten: 16757
Lid geworden op: 18 feb 2003, 22:02
Twitter: meon
Locatie: Bree
Uitgedeelde bedankjes: 582 keer
Bedankt: 780 keer
Provider

Lukse schreef:Die groeperen is toch gemakkelijk met php te doen?
Enlighten me!
Lukse
Premium Member
Premium Member
Berichten: 662
Lid geworden op: 28 okt 2003, 20:51

Code: Selecteer alles

$prev_date = "";
while($row = mysql_fetch_array($result)) {
    if($row['date'] != $prev_date) {
        echo $row['date'];
    }
    echo $row['title'];
    $prev_date = $row['date'];
}
Zoiets?
(gauw uit het hoofd geschreven, niet getest)
Plaats reactie

Terug naar “Development”