2013-05-25 225 views
0

我有一個表格,每行有一個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。

+0

輸入範圍是11,12,1,2? –

+0

是的。這意味着該行在11月開始,並在2月結束。 – user1115660

回答

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

它不能解決搜索範圍爲1月 - 3月(1..3)並且有一行包含start_date的情況:Dec-2010,end_date:Dec -2011。這個推出會給12..24不重疊1..3。 – user1115660

+0

哦,沒錯。但我確定有一個很好的模塊解決方案,但沒有在查詢中列出數字1..12 ...我只是試圖避免使用「或」子句,因爲它會殺死索引使用... – flaschenpost

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月份。

+0

我喜歡你的解決方案。我無法弄清楚如何在軌道中運行它... – user1115660

+0

在與積極記錄軌道? –

+0

不,我知道活動記錄不能做到這一點。我設法運行:SELECT DISTINCT * FROM Table,(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;在sqlite控制檯,但我不知道如何插入此表達式到活動記錄查找/其中。它抱怨'a' – user1115660

0

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