2011-11-04 3 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 조건을 작성합니다?


명확한 설명 : 나는대로 지금까지, 정말 가능하지 PHP와 같은 다른 언어를 통해 내가 저장 프로 시저와 함께 일하고 있어요 순수 SQL에서 솔루션 (그래서 동적 주입되어 찾고 있어요 알고 있음), 날짜 목록이 string (HTML 양식 입력)으로 쿼리에 전달됩니다. 순차적으로 BETWEEN 문으로 나누고 싶습니다. 프로그래밍 방식으로 SQL에서 처리 할 수는 있지만, 어떻게 처리해야하는지 전혀 모릅니다. 당신은 달과 달 (som 아래 eom)의 끝의 시작으로 한 달 지정자를 번역 할 수 있습니다

$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

Ah's BETWEEN'! pwnage> _ <+1 –

+0

날짜의 목록은 쿼리에 전달 된 문자열이고, 개별 변수가 아닌 ... 'WHERE record.an_imaginary_date_field IN (2011-01, 2011-05, 2011-10)'... SQL에서 별도의 값을 얻기 위해 해당 문자열을 구문 분석 할 방법이 없다면? – neezer

+0

@neezer : 클라이언트에서 값을 분리하는 것이 가장 좋습니다. –

0

과 :

는 기본적으로, 나는 다음과 같은 순수 SQL의 논리를 표현하는 방법이 필요합니다 스스로 수행

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; 

그래서, 우리는 쌍 DATE 및 DATETIME으로 각 '2011-01'를 변환 한 다음 중복을 계산한다. (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

관련 문제