Tengo la siguiente tabla de personas y sus cumpleaños:
name birthday ---------------------- yannis 1979-06-29 natalia 1980-08-19 kostas 1983-10-27 christos 1979-07-22 kosmas 1978-04-28
y no tengo ni idea de cómo orderar los nombres de cuán cerca está el cumpleaños de hoy. Entonces, para NOW () = 2011-09-08, el resultado orderado debería ser:
kostas 1983-10-27 kosmas 1978-04-28 yannis 1979-06-29 christos 1979-07-22 natalia 1980-08-19
Estoy buscando un hack rápido, realmente no me importa el performance (el proyecto de mascota – table tendrá less de 1000 loggings), pero por supuesto, cada sugerencia será muy apreciada.
Aquí hay una manera:
SELECT name, birthday, birthday + INTERVAL(YEAR(CURRENT_TIMESTAMP) - YEAR(birthday)) + 0 YEAR AS currbirthday, birthday + INTERVAL(YEAR(CURRENT_TIMESTAMP) - YEAR(birthday)) + 1 YEAR AS nextbirthday FROM bd ORDER BY CASE WHEN currbirthday >= CURRENT_TIMESTAMP THEN currbirthday ELSE nextbirthday END
SQLFiddle
Parece ser bastante rápido, no hay problemas con los años bisiestos:
SELECT * FROM `people` ORDER BY CONCAT(SUBSTR(`birthday`,6) < SUBSTR(CURDATE(),6), SUBSTR(`birthday`,6))
Все гениальное – просто! 😉
SELECT name , birthday FROM TableX ORDER BY DAYOFYEAR(birthday) < DAYOFYEAR(CURDATE()) , DAYOFYEAR(birthday)
No, lo anterior puede producir resultados de error, debido a los años con 366 días. Esto es correcto:
SELECT name , birthday FROM ( SELECT name , birthday , MONTH(birthday) AS m , DAY(birthday) As d FROM TableX ) AS tmp ORDER BY (m,d) < ( MONTH(CURDATE()), DAY(CURDATE()) ) , m , d
Si su tabla crece a más de unos pocos miles de loggings, será muy lenta. Si desea una consulta rápida, agregue campos con el mes y el día y tenga un índice el (bmonth,bday)
o agréguelos como un solo campo, ya sea Char ( 08-17
o 0817
para el 17 de agosto) o Int ( 817
para el 17 -Aug) y un índice en ese campo.
No es bonito, pero funciona
SELECT * ,CASE WHEN BirthdayThisYear>=NOW() THEN BirthdayThisYear ELSE BirthdayThisYear + INTERVAL 1 YEAR END AS NextBirthday FROM ( SELECT * ,birthday - INTERVAL YEAR(birthday) YEAR + INTERVAL YEAR(NOW()) YEAR AS BirthdayThisYear FROM bd ) AS bdv ORDER BY NextBirthday
Lo probaría así (pero esto no está probado):
SELECT name, birthday FROM birthdays ORDER BY ABS( DAYOFYEAR(birthday) - (DAYOFYEAR(CURDATE()) ) ASC
EDITAR:
cambió el order de DESC
a ASC
porque desea get el más lejano primero, no el más cercano.