Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

[mySql] Order bij datum -> nu,komend,verleden

Pagina: 1
Acties:

  • Aloys
  • Registratie: Juni 2005
  • Niet online
Hallo,

Eigenlijk zegt mijn titel al precies wat ik wil, namelijk een mysqlquery die rijen kan sorteren op datum en dan als eerste het agenda-punt van vandaag laat zien (als die er is) en dan de komende (eerste volgende als eerste enz). Daarna mogen de oude agenda punten nog terugkomen (oudste als laatste).

Ik ben dus flink wezen zoeken en kwam uit op de volgende query volgens een comment op mysql.net:
SQL:
1
2
3
4
select * from agenda where categorie = 2
order by post_datum = now() desc,
post_datum > now() asc,
post_datum < now() desc;


Dit doet echter niet wat ik graag wil, de query wordt wel uitgevoerd, maar het resultaat wordt niet gesorteerd. Wie weet hoe ik dit wel voor elkaar krijg, of moet ik 2 queries gebruiken?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Uh geen idee waarom MySQL dit soort brakke syntax pikt uberhaupt. Order by sorteert een result-set, hij hangt er geen conditions op of dat soort dingen. Je sorteert nu hoe dan ook op meaningless booleans.

Je zoekt UNION ALL, of moet gewoon nog tig keer simpeler 3 losse queries vanuit je code pompen.

Professionele website nodig?


  • mithras
  • Registratie: Maart 2003
  • Niet online
In principe wil je dus sorteren op aflopende datum, waarbij alleen vandaag eruit springt. Sorteer dan ook in mysql op aflopende datum en pik er vandaag tussenuit in je controller.

  • Aloys
  • Registratie: Juni 2005
  • Niet online
Nee, dat is niet helemaal waar, was het maar zo simpel :p . Ik wil de huidige datum boven, daarna de komende en daaronder pas de oude agendapunten.

Ik krijg het inderdaad wel netjes met UNION voor elkaar :) , maar dan moet ik via php nog steeds gaan rekenen. Kan ik een bepaald veld toevoegen met een bepaalde waarde (bijv. "nu", "komend", "geweest")?
SQL:
1
2
3
(SELECT * FROM n01_berichten WHERE categorie = 2 AND post_datum >= NOW() order by post_datum ASC)
UNION 
(SELECT * FROM n01_berichten WHERE categorie = 2 AND post_datum < NOW() order by post_datum DESC);

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Doe gewoon 3 queries in je code.

Professionele website nodig?


  • Psychokiller
  • Registratie: Oktober 2001
  • Niet online
Wellicht dat iets als:
ORDER BY CASE WHEN DATE(post_datum) = DATE(now()) THEN 1 ELSE CASE WHEN post_datum > NOW() THEN 2 ELSE 3 END END ASC, post_datum DESC

Kan zijn dat je dat statement ook in je Select moet zetten.

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Het kan wel inderdaad dmv case when, unions etc. , maar wellicht stel je de verkeerde vraag. Als enkel het sorteren van wat rows zo ingewikkeld is, is die volgorde dan wel intuitief? Ik heb iig nog nooit zo'n agenda gezien, en als je zonder limits van deze 3 periodes gaat selecteren weet ik ook zeker dat ik na de 1e keer dat ik zo'n agenda zou zien, de agenda functie voortaan zou willen ontwijken. :P

KISS. Maak een duidelijk overzicht voor het huidige uur, dag of week en that's it. Met zomaar wat in de toekomst en verleden selecteren help je niemand. Als je een lijstje 'eerste X aanstaande items' wil, kan dat met een doodeenvoudige, supersnelle en op zichzelf staande query.

{signature}


  • dik_voormekaar
  • Registratie: April 2003
  • Laatst online: 14:49
Waarom niet iets als: ORDER ABS(DATE(post_datum) - DATE(now() ) DESC

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Omdat je dan helemaal complete chaos met items uit toekomst en verleden hebt. :X 8)7. Ben ik dan de enige persoon in dit topic die denkt dat een agenda vooral overzichtelijk moet zijn? :>

En met dergelijke functies in een order by durf ik te garanderen dat losse queries niet alleen helderder en logischer zijn, maar ook sneller. ;)

{signature}


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Voutloos schreef op zaterdag 21 juni 2008 @ 15:52:
Omdat je dan helemaal complete chaos met items uit toekomst en verleden hebt. :X 8)7. Ben ik dan de enige persoon in dit topic die denkt dat een agenda vooral overzichtelijk moet zijn? :>
Ik ook? :P
En met dergelijke functies in een order by durf ik te garanderen dat losse queries niet alleen helderder en logischer zijn, maar ook sneller. ;)
Daarom zei ik het ook al ;)

Professionele website nodig?


  • Aloys
  • Registratie: Juni 2005
  • Niet online
Het gaat hier ook niet echt om een agenda. Ik gebruik dit alleen om als voorbeeld, omdat het wel precies op dezelfde manier zou kunnen. Het gaat om een lijstje activiteiten op een website. De activiteiten die als eerste komen moeten uiteraard bovenaan staan, enz... Hier komen geen gigantische aantallen aan rijen vrij en standaard limit ik op 30 (ookal stond dat hier niet in de de voorbeeld query).

Ik heb inmiddels wat ik wilde via unions en dat schiet prima op. Ik ben blij :)

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Mjah kijk het enige wat een union doet is resultsets samenvoegen. Omdat in het voorbeeld wat je geeft alle 3 de partials een andere afhandeling vereisen is het wat vreemd om dit in een union te doen - dan moet je code detecteren waar de overgang ligt tussen de 3 zeer verschillende blokken data. Je kunt dan meestal beter de lichte extra overhead van 3 losse queries uitvoeren nemen en je business logic een tig factoren simpeler houden.

Professionele website nodig?


  • pedorus
  • Registratie: Januari 2008
  • Niet online
Dat een union hier werkt komt alleen maar door de huidige MySQL-implementatie. Het kan breken in toekomstige versies. "UNION by default produces an unordered set of rows"
Dat dit ooit gaat breken is nog wel waarschijnlijk ook, aangezien er dan heel mooi meerdere cores gebruikt kunnen worden.

Ik snap nog steeds niet helemaal wat het nut is op een website. Je hebt een lijstje met huidige en toekomstige events, en je plakt daarachter opeens events uit het verleden?

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 18:11
Slechte vraagstelling zeg...

Definieer nu.

Is nu de exacte tijd, deze minuut, dit uur, deze dag?

Zodra je dat weet zou je volgens mij een berekende kolom kunnen toevoegen met als argument je "nu". Ligt iets voor die tijd, dan is de waarde van die extra kolom 2. Ligt iets na die tijd 1. Is iets die tijd dan is die extra kolom 0.

Resultaat sorteren op je extra kolom en vervolgens op je datum/tijd veld.

  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online
Aloys schreef op zaterdag 21 juni 2008 @ 14:38:
Hallo,

Eigenlijk zegt mijn titel al precies wat ik wil, namelijk een mysqlquery die rijen kan sorteren op datum en dan als eerste het agenda-punt van vandaag laat zien (als die er is) en dan de komende (eerste volgende als eerste enz). Daarna mogen de oude agenda punten nog terugkomen (oudste als laatste).

Ik ben dus flink wezen zoeken en kwam uit op de volgende query volgens een comment op mysql.net:
SQL:
1
2
3
4
select * from agenda where categorie = 2
order by post_datum = now() desc,
post_datum > now() asc,
post_datum < now() desc;


Dit doet echter niet wat ik graag wil, de query wordt wel uitgevoerd, maar het resultaat wordt niet gesorteerd. Wie weet hoe ik dit wel voor elkaar krijg, of moet ik 2 queries gebruiken?
je moet uiteindelijk natuurlijk ook nog op de datum zelf sorteren, nu sorteer je alleen op het feit of een datum groter of kleiner is... de booleans geven false (0) of true (1) terug... dus morgen overmorgen en overovermorgen geven bij "post_datum > now()" alledrie 1 terug... en een rijtje van drie 1-tjes sorteren heeft weinig effect...
voeg dus aan het einde : ", post_datum" toe en je bent klaar...

  • Aloys
  • Registratie: Juni 2005
  • Niet online
Ik sorteer ook nog wel op de datum. Ik heb de query nu als volgt:
SQL:
1
2
3
4
5
SELECT *, "new" as time_pos FROM table_posts 
WHERE categorie = 2 AND post_datum >= NOW() order by post_datum ASC limit 0,30)
UNION 
SELECT *,  "old" as time_pos FROM table_posts 
WHERE categorie = 2 AND post_datum < NOW() order by post_datum DESC limit 0,30);

Dit werkt perfect voor mij. Als 1 van beide query's (of beiden) geen resultaat oplevert gaat er niets fout. Ik loop dmv. php sowieso door de rijen (html opmaak), dus kan ik direct wanneer "time_pos = old" voorkomt een stukje html ertussen plakken.

Ik weet dat dit waarschijnlijk niet de beste/netste oplossing is, maar het moest wel compatible blijven met andere functies die ik gemaakt heb. Door query te gebruiken blijft de data hetzelfde en hoeft er alleen eventjes gechecked te worden op time_pos=old. :)

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 16:34

MueR

Admin Devschuur® & Discord

is niet lief

Hoe zouden 3 queries dan niet compatible zijn met je andere functies? Je bent nu efficientie en overzichtelijkheid aan het vergooien omdat iets brak is opgezet?

Anyone who gets in between me and my morning coffee should be insecure.

Pagina: 1