Suppose the following table structure:
Event:
id: integer
start_date: datetime
end_date: datetime
Is there a way to query all of the events that fall on a particular day of the week? For example, I would like to find a query that would find every event that falls on a Monday. Figuring out if the start_date or end_date falls on a Monday, but I’m not sure how to find out for the dates between.
Pure SQL is preferred since there is a bias against stored procedures here, and we’re calling this from a Rails context which from what I understand does not handle stored procedures as well.
The subquery iterates all days from
start_datetoend_date, checks each day, and if it’s aMonday, returns1.You can easily extend this query for more complex conditions: check whether an event falls on
ANY Monday OR Friday 13th, for instance:Note that I use
MOD(start_date - TO_DATE(1, 'J') + level - 1, 7)instead ofTO_CHAR('D'). This is becauseTO_CHAR('D')is affected byNLS_TERRITORYand should not be used for checking for a certain day of week.This query does not use any indexes and always performs a full table scan. But this is not an issue in this specific case, as it’s highly probable that a given interval will contain a
Monday.Even if the intervals are
1day long, the index will return14%of values, if intervals are longer, even more.Since
INDEX SCANwould be inefficient in this case, and the inner subquery is very fast (it uses in-memoryFAST DUALaccess method), this, I think, will be an optimal method, both by efficiency and extensibility.See the entry in my blog for more detail: