I am looking around for a solution but have not succeeded so far. My MySQL table ($people_table) holds birthdays in a column "birthdatetr" of type "date", and the data is stored in the format "YYYY-MM-DD" (example: 1789-04-02)

Depending on the current date, I specify a range of interest. I am calculating the current week with:

$lastmonday = date('m-d', strtotime('last monday'));
$nextsunday = date('m-d', strtotime('next sunday'));

I would like to Select all rows, where the birthday is within this range. (The application is website with genealogical data, which displays all birthdays that happened in the same week so and so many years ago)

I managed to get it somehow done by calculating the day of the year:

$lastmonday_doy = date('z', strtotime('last monday'));
$nextsunday_doy = date('z', strtotime('next sunday'));

SELECT * FROM $people_table WHERE DAYOFYEAR(birthdatetr) BETWEEN $lastmonday_doy AND $nextsunday_doy;

The idea was to bypass any trouble with the month wrap. But this still does not work when the year wraps. Also, I was concerned whether this is very expensive, because the table may hold >5000 rows in the future.

Finally, the DAYOFYEAR() approach does not take leap years into account.


At the moment, there is another implementation roughly working, but I don't understand it and I cannot change it for that reason. It looks very complex:

$query = "SELECT birthdatetr, YEAR(birthdatetr) AS  BirthYear, birthdatetr + INTERVAL YEAR('" . $datetouse . "') - YEAR( birthdatetr ) + ( (birthdatetr + INTERVAL YEAR('" . $datetouse . "') - YEAR(  birthdatetr ) YEAR) < '" . $datetouse . "') YEAR as nextbirthday
FROM $people_table
WHERE DATEDIFF( birthdatetr + INTERVAL YEAR('" . $datetouse . "') - YEAR(  birthdatetr ) + ( ( birthdatetr + INTERVAL YEAR('" . $datetouse . "') - YEAR(birthdatetr)  YEAR) < '" . $datetouse . "') YEAR, '" . $datetouse . "') <= $futuredays ORDER BY  nextbirthday, birthdatetr";

Here, the current date is $datetouse, and the $futuredays specifies the length of the range. (in this example, $futureday=7; )

Is there a light-weight way to SELECT desired data?

Thanks!

有帮助吗?

解决方案

For the one week requirement could be simpler to replace the

WHERE DAYOFYEAR(birthdatetr) BETWEEN $lastmonday_doy AND $nextsunday_doy

with

WHERE DAYOFYEAR(birthdatetr) in (7 day numbers for the 7 weekdays)

and pass 7 parameters to the query (monday, tuesday... sunday)

其他提示

Ok, here is the final SQL statement. Thanks to StanislavL:

SELECT birthdatetr as datedisplay FROM tng_people 
WHERE DATE_FORMAT(birthdatetr, '%m-%d') IN ('05-12', '05-13', '05-14', '05-15', '05-16', '05-17', '05-18') 

UNION ALL
SELECT deathdatetr as datedisplay FROM tng_people 
WHERE DATE_FORMAT(deathdatetr, '%m-%d') IN ('05-12', '05-13', '05-14', '05-15', '05-16', '05-17', '05-18')

UNION ALL
SELECT marrdatetr as datedisplay FROM tng_families 
WHERE DATE_FORMAT(marrdatetr, '%m-%d') IN ('05-12', '05-13', '05-14', '05-15', '05-16', '05-17', '05-18') 

ORDER BY DAYOFWEEK(datedisplay)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top