[MySQL] Sorteren op de oudste van twee datums

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 11:37
Gisteren dacht ik het eindelijk voor elkaar te hebben, maar nu zie ik dat het nog steeds niet werkt zoals het zou moeten. Dus toch hier maar even een topic openen, misschien heeft iemand een heldere ingeving!

Situatie

Zie hieronder een versimpelde versie van de tabellen.

event
- id (INT, PK, AI)
- name (VARCHAR 140)
- type_id (INT)
- start_date (DATE)

event_history
- id (INT, PK, AI)
- event_id (INT)
- date (DATE)

type
- id (INT, PK, AI)
- name (VARCHAR 140)
- period (INT)

Wat wil ik?

Sorteren op event.start_date of event_history.date in oplopende volgorde (ASC). Daarbij word type.period, een aantal dagen, bij de datums opgeteld.

Wat heb ik al geprobeerd?

Hieronder een versimpelde versie van de query die ik ongeveer uitvoer. De LEAST() mogelijkheid kwam ik op Google tegen, maar dat gaat meestal om twee vaste datums, zonder de periode te verlengen en zonder subquery.

SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT
    event.*,
    (SELECT event_history.date FROM event_history WHERE event_history.event_id = event.id ORDER BY event_history.date DESC LIMIT 1) AS event_history_date

FROM
    event
    
        INNER JOIN type ON (type.id = event.type_id)

ORDER BY
    LEAST (
        IF (event_history_date IS NULL, NOW(), DATE_ADD(event_history_date, INTERVAL type.period DAY)),
        DATE_ADD(event.start_date, INTERVAL type.period DAY)
    ) ASC


Wat doet het nu?

Nou zonder dat er rows in event_history zitten, werkt het al niet. LEAST() zou de minste van de twee moeten teruggeven die daarna ASC gesorteerd worden.

Bij het weergeven van de datum + periode krijg ik onderstaande terug. Als de 1e en 2e van plek zouden wisselen werkt het naar behoren, maar helaas!

- 2015-03-11
- 2014-08-23
- 2015-06-19

Bij het weergeven van de LEAST() krijg ik 2014-06-24 terug, kortom vandaag!

Rubber duck...

Goed, in de alinea hierboven ben ik erachter gekomen dat NOW() roet in het eten gooit. Echter wil ik jullie deze kwestie alsnog voorleggen. Misschien hebben jullie verbeteringen en een oplossing voor NOW(); gewoon een idioot jaartal opgeven ofzo?

Acties:
  • 0 Henk 'm!

  • cannibal
  • Registratie: Maart 2001
  • Laatst online: 16:50
Hoe belangrijk is de performance en de context van het uitvoeren van de query, anders is het met een user defined function niet zo'n probleem.

Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 11:37
Ik denk dat ik het opgelost heb met het onderstaande. Dat lijkt goed te werken, al heb ik nog niet alle mogelijke situaties getest.

SQL:
1
2
3
4
5
6
ORDER BY
    IF (
        event_history_date IS NULL,
        DATE_ADD(event.start_date, INTERVAL type.period DAY),
        DATE_ADD(event_history_date, INTERVAL type.period DAY)
    ) ASC


De query moet performant genoeg zijn, al heb ik nog niks aan optimalisatie gedaan.