Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
260 views
in Technique[技术] by (71.8m points)

switch statement - MySQL Query for Date Part

I have two tables...

tblEvent
--------
id
date

tblEventRecurring
-----------------
event_id
date_part
end_date

The relationship is I can have an event that is either on one day (date in tblEvent) or recurs on an interval (Day, Week, Month, Year) which ties in the tblEventRecurring table.

For example, if I put in an event for Feb. 10 recurring until Feb. 28 I'd have...

tblEvent
--------
id = 1
date = 2012-02-10

tblEventRecurring
-----------------
event_id = 1
date_part = D
end_date = 2012-02-28

what is the best way structure a query to get all dates where the following conditions are met...

  • tblEvent.date = today
  • if tblEventRecurring.date_part = D and today < end_date
  • if tblEventRecurring.date_part = W and today is the same day of week (sun-sat) as tblEvent.date and < end_date
  • if tblEventRecurring.date_part = M and today is the same day of month as tblEvent.date and < end_date etc.

Is there one solution more efficient than another? Is this a good time to use IF or CASE or a bunch of AND/OR statements?

Thanks for any guidance. D.

Since I was down voted for not researching, I thought I'd post my final query... I was struggling with some of the AND/OR and parentheses. I DID research and was reading more on CASE which I've never used so I hoped someone could possibly guide my query using it.

# where the current date is 2012-02-12
SELECT e.record_id, e.event_date, 
       DATE_FORMAT(e.event_time, '%l:%i %p') AS event_time, 
       e.category, pm.person_id, pm.status, pm.active
FROM tblEvent e 
JOIN tblTABLE pmd ON pmd.record_id = e.reference_id 
JOIN tblTABLE2 pm ON pm.record_id = pmd.t_id 
LEFT OUTER JOIN tblEventRecurring er ON er.event_id = e.record_id 
WHERE e.category = 'CAT' 
AND pm.planet_id = 1 # id of person
AND pm.active = 1 
AND pm.status = 'Read Only' 
AND (
    e.event_date = '2012-02-12' # the event is on current date
    OR ( 
        # recurring with no end date or end date in future
        er.end_date = '0000-00-00' OR er.end_date >= '2012-02-12'
        AND ( 
            e.event_date <= '2012-02-12' # recurring starts today or in past
            AND ( # meets any of the following
                (er.date_part = 'D') 
                OR (er.date_part = 'W' AND dayofweek('2012-02-12') = dayofweek(e.event_date)) 
                OR (er.date_part = 'M' AND dayofmonth('2012-02-12') = dayofmonth(e.event_date)) 
                OR (er.date_part = 'Y' AND (day('2012-02-12') = day(e.event_date) AND MONTH('2012-02-12') = MONTH(e.event_date)))
            ) 
        ) 
    )
)
ORDER BY e.event_time
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is essentially the same as Mosty's answer but with the LEFT JOIN to retrieve events that occur only once. This will retrieve all events for today.

SELECT *
FROM `tblEvent`
LEFT JOIN `tblEventRecurring`
    ON `tblEvent`.`id` = `tblEventRecurring`.`event_id`
WHERE (`tblEvent`.`date` = CURRENT_DATE AND `tblEventRecurring`.`event_id` IS NULL)
OR (
    CURRENT_DATE BETWEEN `tblEvent`.`date` AND `tblEventRecurring`.`end_date`
    AND (
        (`tblEventRecurring`.`date_part` = 'D') OR
        (`tblEventRecurring`.`date_part` = 'W' AND DAYOFWEEK(`tblEvent`.`date`) = DAYOFWEEK(CURRENT_DATE)) OR
        (`tblEventRecurring`.`date_part` = 'M' AND DAYOFMONTH(`tblEvent`.`date`) = DAYOFMONTH(CURRENT_DATE))
    )
)

I am not sure whether this is of any use to you but thought I would post it as I have done it now

SELECT *
FROM `date_list`
LEFT JOIN (
    SELECT `tblEvent`.`id`, `tblEvent`.`date`, `tblEvent`.`name`, `tblEventRecurring`.`date_part`, `tblEventRecurring`.`end_date`
    FROM `tblEvent`
    LEFT JOIN `tblEventRecurring`
        ON `tblEvent`.`id` = `tblEventRecurring`.`event_id`
) AS `events`
    ON (
        `events`.`date` = `date_list`.`date`
    )
    OR (
        `date_list`.`date` BETWEEN `events`.`date` AND `events`.`end_date`
        AND (
            (`events`.`date_part` = 'D') OR
            (`events`.`date_part` = 'W' AND DAYOFWEEK(`events`.`date`) = DAYOFWEEK(`date_list`.`date`)) OR
            (`events`.`date_part` = 'M' AND DAYOFMONTH(`events`.`date`) = DAYOFMONTH(`date_list`.`date`))
        )
    )
WHERE `date_list`.`date` BETWEEN '2012-02-06' AND '2012-02-12'
ORDER BY `date_list`.`date`;

It assumes a date_list table consisting of a single date field containing a continuous list of dates.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...