2011-11-04 138 views
3

我有YYYY-MM格式的日期列表,並且我有一個表格,其中包含starts_atends_at列的記錄。MySQL:IN子句的開始日期和結束日期之間的日期?

我想要查找傳入列表中的任何給定日期在starts_atends_at範圍內的所有記錄。

因此,鑑於2011-01, 2011-05, 2011-10,我想:

| id | starts_at   | ends_at    | title        | 
| 3 | 2010-12-05 00:00:00 | 2011-02-02 00:00:00 | something cool     | 
| 4 | 2011-03-14 00:00:00 | 2011-05-01 00:00:00 | something else really cool  | 
| 5 | 2011-10-31 00:00:00 | 2012-12-23 00:00:00 | argh! end of the world! not cool! | 

...而這些記錄將被省略:

| id | starts_at   | ends_at    | title        | 
| 6 | 2010-10-05 00:00:00 | 2010-12-02 00:00:00 | something uncool     | 
| 7 | 2011-03-14 00:00:00 | 2011-04-31 00:00:00 | something else really uncool  | 
| 8 | 2011-12-23 00:00:00 | 2013-01-01 00:00:00 | yay! we're still alive! cool!  | 

我怎麼會寫在SQL這WHERE條件?


澄清:我正在尋找在純SQL(通過一些其他語言如PHP的解決方案,我用存儲過程的工作,所以動態注入是不是真的有可能,只要我知道),並將日期列表作爲string(HTML表單輸入)傳遞給查詢。我很樂意將它分解爲連續的BETWEEN語句,如果我可以用SQL編程的話,但我不知道該怎麼做。

基本上,我需要一種方法來表達純粹的SQL以下邏輯:

$months = explode(',', '2011-01,2011-05,2011-10'); 
$q = "SELECT records.* FROM records WHERE"; 
foreach($months as $month) { 
    $q .= " '$month' BETWEEN records.starts_at AND records.ends_at OR"; 
} 
$q = substr($q, 0, -3) . ';'; 

回答

2
SELECT id, starts_at, ends_at, title 
FROM yourtable 
WHERE '2011-01-01' BETWEEN starts_at AND ends_at 
OR '2011-05-01' BETWEEN starts_at AND ends_at 
OR '2011-10-01' BETWEEN starts_at AND ends_at 
+0

啊'BETWEEN'!pwnage> _ <+1 –

+0

不完全是我之後...日期列表是傳遞給查詢的字符串,不是作爲單個變量......類似這樣的:'WHERE record.an_imaginary_date_field IN(2011-01,2011-05,2011-10)'......除非SQL中有解析該字符串以獲取單獨值的方法嗎? – neezer

+0

@neezer:這可能是最好的解析它來分離客戶端的值。 –

0

您可以在一個月符轉化爲一個月,一個月(som及以下eom)結束的開始和自己動手:

SET sql_mode='ansi'; 

SELECT neezer.* 
    FROM neezer 
    JOIN (SELECT m || '-01' AS som, 
       DATE_SUB(DATE_ADD(m || '-01', INTERVAL 1 MONTH), INTERVAL 1 SECOND) AS eom 
      FROM (SELECT '2011-01' AS m 
       UNION ALL 
       SELECT '2011-05' 
       UNION ALL 
       SELECT '2011-10') d) month_intervals 
     ON som <= ends_at AND eom >= starts_at; 

所以,我們把每個'2011-01'成成對DATE和DATETIME,然後計算重疊。 (我們將eom轉換爲'YYYY-MM-DD 23:59:59'的原因是,'2011-01'匹配的時間間隔爲starts_at'2011-01-01 01:00:00'(否則eom將被強制爲00:00 :00在第一天,並不符合我們的starts_at

+0

嗯,有什麼理由不在這裏使用BETWEEN嗎?另外,無論如何在純SQL中以編程方式執行此操作?看到我上面的編輯我的意思... – neezer

+0

@neezer,我假設'starts_at'和'ends_at'是暫時類型,而不是字符串。查看我對MarkByer答案的評論。至於你的「純SQL」問題,不。但是,您自己的設計的存儲過程可能能夠拆分字符串並吐出正確的查詢或使用您關心的日期範圍填充臨時表。 – pilcrow

相關問題