Reputation: 821
I have a MySQL table with the following structure:
id | date | type | description
---------------------------------------------------
0 | 1979-09-20 | 'bday' | 'Birthday Employee1 '
1 | 1984-05-04 | 'bday' | 'Birthday Employee2 '
2 | 1989-01-04 | 'bday' | 'Birthday Employee3 '
3 | 2013-10-10 | 'visit' | 'Visit of Visitor1 '
This table should handle all upcoming and bygone events in an employee portal. There are two different types of events; birthdays and visits. These are declared as string in the column type. Birthdays should only be entered once, not every year, so there is the need of a complexe query to handle this case:
SELECT * ,
CASE type
WHEN 'bday'
THEN
(CASE
WHEN ADDDATE( date, INTERVAL YEAR( NOW( ) ) - YEAR( date ) YEAR )< NOW()
THEN ADDDATE(ADDDATE(datum,INTERVAL YEAR(NOW())- YEAR(date) YEAR),
INTERVAL 1 YEAR)
ELSE ADDDATE( date, INTERVAL YEAR( NOW( ) ) - YEAR( date ) YEAR )
END)
ELSE date
END
AS dates
FROM events
WHERE date > NOW() AND type='visit' OR ADDDATE(date, INTERVAL
YEAR NOW())-YEAR( date ) YEAR) > NOW() AND type='bday'
ORDER BY dates ASC
LIMIT 0 ,10
This query doesn't work for me since i added the nested case clause in the brackets. I replaced it for the following line
ADDDATE( date, INTERVAL YEAR( NOW( ) ) - YEAR( date ) YEAR )
This worked but the problem is that - as you may see in the nested CASE clause -, birthdays which already took place in the recent year won't be selected. So the purpose of the extra CASE is to determine whether the year should be like 2013 or 2014 ( if it already took place in 2013).
This is quite important for birthdays in the first two weeks of the year. The reminding notification has to be seen already in the year before, otherwise it wouldn't make that much sense.
So actually i just need to figure out why the nested CASE clause is not working. It's also possible that there are obviously easier ways to solve this, but right now I am not able to see them.
Upvotes: 0
Views: 222
Reputation: 115600
I suppose you want to show "near" future events and birthdays. One way would be to separate the logic into 3 parts and UNION
them. The 3 parts would be:
birthdays of next year
( SELECT id, date, type, description,
date AS dates
FROM events
WHERE type='visit'
AND date > NOW()
)
UNION ALL
( SELECT id, date, type, description,
ADDDATE(date, INTERVAL (YEAR(NOW())-YEAR(date)) YEAR)
FROM events
WHERE type='bday'
AND ADDDATE(date, INTERVAL (YEAR(NOW())-YEAR(date)) YEAR) > NOW()
)
UNION ALL
( SELECT id, date, type, description,
ADDDATE(date, INTERVAL (1+YEAR(NOW())-YEAR(date)) YEAR)
FROM events
WHERE type='bday'
)
ORDER BY dates ASC
LIMIT 0, 10 ;
Your CASE
seems correct, too. But if you want all birthdays to be considered, you should replace the OR ADDDATE(date, INTERVAL YEAR NOW())-YEAR( date ) YEAR) > NOW() AND type='bday'
condition with the simple OR type='bday'
Upvotes: 1
Reputation: 1404
You have to change YEAR DIFF part:
SELECT ADDDATE(date, INTERVAL (FLOOR(DATEDIFF(CURDATE(),date)/365)) YEAR )<NOW()
example for id=0
SELECT ADDDATE('1979-09-20',
INTERVAL (FLOOR(DATEDIFF(CURDATE(),'1979-09-20')/365)) YEAR )< NOW();
Upvotes: 0