选择几个月的记录

时间:2013-05-25 17:46:08

标签: mysql sql ruby-on-rails ruby sqlite

我有一张表格,每行有一个start_dateend_dateend_date可以与开始日期不同。

我需要选择与输入月份范围重叠的所有记录。

例如:

n  start_date  end_date  
1  2010-12-03  2010-03-29  // months are 12,1,2,3  
2  2012-03-11  2010-06-24  // months are 3,4,5,6  
3  2010-06-17  2010-10-04  // months are 6,7,8,9,10  
4  2010-07-03  2010-09-21  // months are 7,8,9  
5  2010-04-21  2011-05-13  // months are 1..12 

输入范围是3,4,5,6。输出行应为:1,2,3,5。 只有第4行在任何月份都没有重叠。

如何在SQlite / MySQL中执行此操作?

我正在使用Ruby on Rails。

3 个答案:

答案 0 :(得分:1)

“输入范围”听起来像连接范围。因此,如果没有12个月的范围,典型的解决方案将是where month(start_date) <= $end_month and month(end_date) >= $start_month

但是这样我们需要模数的整个范围。我会把关系推广到1月24日。

这意味着范围是:

month(start_date) ... month(end_date) + 12*(year(end_date) - year(start_date))

现在必须推出给定范围$from, $to

if($to < $from){ 
    $to += 12;
}

关系推出

month(start_date) <= $to 
and (month(end_date) + 12*(year(end_date) - year(start_date))) >= $from

希望有所帮助。

答案 1 :(得分:0)

这样的事情应该在一个SQL中完成: -

SELECT DISTINCT n
FROM SomeTable,
(SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 10 UNION SELECT 11) a
WHERE DATE_ADD(DATE_SUB(SomeTable.start_date, INTERVAL DAYOFMONTH(SomeTable.start_date)-1 DAY), INTERVAL a.i MONTH) <= SomeTable.end_date
AND MONTH(DATE_ADD(DATE_SUB(SomeTable.start_date, INTERVAL DAYOFMONTH(SomeTable.start_date)-1 DAY), INTERVAL a.i MONTH)) IN (3, 4, 5, 6)

只要结果日期小于或等于该行的结束日期,每个开始日期最多可累计11个月。这可能会为每个初始行提供12个结果行,在该范围内每个月一个行,并且使用IN子句针对您要检查的月份进行检查。

括号内DATE_SUB的奇怪玩法是使用该月的第一天。否则在2013年增加一个月:02:28会给出一个大于2013:03:01的日期,因此如果没有这个游戏,你只会得到2月而不是3月。

答案 2 :(得分:0)

SomeClass.where("start_date >= ? end_date <= ?", start_date.beginning_of_month, end_date.end_of_month)

相关问题