MySQL“사이”조항이 포함되지 않습니까?


142

between절로 쿼리를 실행 하면 끝 값을 제외하는 것으로 보입니다.
예를 들면 다음과 같습니다.

select * from person where dob between '2011-01-01' and '2011-01-31'

이것은 dob'2011-01-01'에서 '2011-01-30'까지의 모든 결과를 얻습니다 . dob'2011-01-31'인 레코드를 건너 뜁니다 . 이 쿼리가 왜 이런 식으로 동작하는지, 어떻게 dob'2011-01-31'인 레코드를 포함하도록 쿼리를 수정할 수 있습니까? 종료 날짜에 1을 추가하지 않고 (사용자가 선택했기 때문에)


아니. 내 MySQL 설치 (버전?) BETWEEN는 두 값 모두에 포함됩니다. 저는 MySQL Server 5.7Windows 10을 사용하고 있습니다.
Green

답변:


181

이 필드 dob에는 아마도 시간 구성 요소가 있습니다.

잘라 내기 :

select * from person 
where CAST(dob AS DATE) between '2011-01-01' and '2011-01-31'

59
대신 CAST(dob AS DATE)더 간결하게 사용할 수 있습니다 DATE(dob).
jkndrkn

11
이것이 작동하는 동안 >=<대신를 사용하면 성능이 향상됩니다 between.
David Harkness

112
를 사용하면 성능이 향상됩니다 dob BETWEEN '2011-01-01 00:00:00' AND '2011-01-31 23:59:59. 때문입니다 DATE(dob)각 행의 값을 계산해야하고 해당 필드에 어떤 인덱스를 사용할 수 없습니다.
joshuahedlund

2
@joshuahedlund이 솔루션에 대한 답변을 추가하십시오. CAST는 그다지 효율적이지 않습니다.
doc_id

3
@joshuahedlund 시간이있는 데이터가있을 때까지 작동합니다 t > 23:59:59 and t < 24:00:00. 왜 잘못 지정된 것을 다루는가 BETWEEN? 오히려 다윗의 조언을 따르고 사용하십시오 WHERE dob >= '2011-01-01' AND dob < '2011-02-01'. 최고의 성능으로 매번 작동합니다.
환멸

300

로부터 MySQL을 수동 :

이는 표현식과 같습니다 (최소 <= expr AND expr <= max)


3
이 답변에 연결된 매뉴얼은 DATE 및 DATETIME 객체를 비교할 때 캐스트가 선호됨을 보여줍니다. 그래서 @tiagoinu는 가장 엄격한 의미에서 가장 완전한 대답을 가지고 있지만 둘 다 자리에 있습니다.
Kingsolmn

@jemminger는 대답이 archrival -postgres guy 에서 온 것이기 때문일 수 있습니다 . : P
nawfal

27
간단히 말해 사이에 포함 되는 것이 있습니다.
라파엘

6
오래된 의견이지만이를 특정 쿼리에 연결하고 싶었습니다. "BETWEEN"은 포함되지만 시간이 지정되지 않은 날짜는 00:00:00까지입니다. 따라서 날짜 범위를 비교하면 마지막 날이 손실됩니다. DATE (dob)에 전화하거나 하루의 끝을 지정하십시오.
wintermute92

그들은 연습이 금이라고 말하고, 내 유스 케이스에서 전혀 포함되지는 않습니다. 왜 이런 일이 발생하는지 궁금합니다. 나는 때때로 시도하고 때로는 작동하지 않습니다. TIME 데이터 필드에 사용하십시오.
Jeffery ThaGintoki

99

문제는 2011-01-31이 실제로 2011-01-31 00:00:00이라는 것입니다. 그것은 하루의 시작입니다. 낮에는 모든 것이 포함되지 않습니다.


19
이것은 실제로 진행 상황을 설명하고 질문에 대답합니다.
Ivan P

3
몇 년이 지난 후에도이 답변은 여전히 ​​최고입니다. 고마워
Strabek

31
select * from person where dob between '2011-01-01 00:00:00' and '2011-01-31 23:59:59'

1
나는 이것에 날짜 가 포함 되지 않지만 하루의 마지막 초 까지의 날짜는 포함되지 않을 것이라는 점은 주목할 가치가 있다고 생각 합니다 . 2011-01-31 23:59:592011-01-31 23:59:58
doc_id

1
MySQL 문서의 rahmanisback BETWEEN이 양방향으로 포함되어 있기 때문에 마지막 초가 포함될 것임을 확인할 수 있습니다. 참조 dev.mysql.com/doc/refman/5.5/en/...
Felype

1
예, @Felype가 옳습니다. 나는 이것을 mysql 데이터베이스에서 직접 확인했다. 23:59:59결과 에도 포함됩니다 . 따라서 두 가지 방법이 모두 포함됩니다.
Lucky

2
경우 dob열이 초 이하의 정밀도로 타임 스탬프는 다음되지 않습니다 BETWEEN'2011-02-01 0시 0분 0초가'대신 사용하지 않는 한 여전히 하루의 마지막 초 내에서 이벤트를 그리워?
질소

1
-1. 포함하지 않습니다 2011-01-31 23:59:59.003. @nitrogen 사용이 2011-02-01 000:00:00됩니다 잘못 왜 2월 1일 ....에 제로 시간을 포함 >=하고 <대신 사용되어야한다.
환멸

6

쿼리에서 참조하는 필드가 날짜 유형 또는 날짜 시간 입니까? 유형입니까?

설명하는 동작의 일반적인 원인은 실제로 날짜 유형을 사용해야하는 DateTime 유형을 사용할 때입니다. 즉, 누군가가 태어난 시간을 정말로 알아야 할 필요가 없다면 날짜 유형을 사용하십시오.

마지막 날이 결과에 포함되지 않는 이유는 쿼리에서 쿼리에 지정하지 않은 날짜의 시간 부분을 쿼리가 가정하는 방식입니다.

즉, 쿼리는 2011-01-30과 2011-01-31 사이의 자정까지 해석되지만 2011-01-31의 하루 후일에 데이터에 값이있을 수 있습니다.

제안 : 날짜 / 시간 유형 인 경우 필드를 날짜 유형으로 변경하십시오.


4

안녕하세요,이 질문은 저에게 효과적입니다.

select * from person where dob between '2011-01-01' and '2011-01-31 23:59:59'

2
select * from person where DATE(dob) between '2011-01-01' and '2011-01-31'

놀랍게도 이러한 변환은 MySQL의 많은 문제에 대한 솔루션입니다.


10
놀랍게도, 이것은 정확히 2 년 전에 받아 들여진 대답 (그리고 몇몇 다른 사람들)이 말한 것입니다.
Chris Baker

0

상위 날짜를 날짜 + 1 일로 설정하므로 귀하의 경우 2011-02-01로 설정하십시오.


1
이것은 2 월 1 일에 0 을 잘못 포함 할 것입니다 .... 이것이 BETWEEN무시되어야하는 이유입니다 . 하지만 >=하고 <대신 사용해야합니다.
환멸

0

다음과 같이 쿼리를 실행할 수 있습니다.

select * from person where dob between '2011-01-01' and '2011-01-31 23:59:59'

날짜가 하드 코딩 된 경우 다른 사람들이 지적한 것처럼.

반면, 날짜가 다른 테이블에있는 경우 다음과 같이 날짜를 추가하고 초를 뺄 수 있습니다 (두 번째 / 시간없이 날짜가 저장된 경우).

select * from person JOIN some_table ... where dob between some_table.initial_date and (some_table.final_date + INTERVAL 1 DAY - INTERVAL 1 SECOND)

dob(응답 된 답변과 같이) fiels 에 캐스트를하지 마십시오. 큰 성능 문제가 발생할 수 있습니다 ( dob필드 에서 인덱스를 사용할 수없는 경우). 또는 과 같은 것을 만들면 실행 계획이에서 using index condition로 변경 될 수 있으므로주의하십시오!using whereDATE(dob)CAST(dob AS DATE)


0

MySql에서는 값 사이에 값이 포함되므로 '2011-01-01'과 '2011-01-31'사이를 얻으려고하면

그것은에서 포함되지 않습니다 2011-01-01 00:00:00개까지 2011-01-31 00:00:00 의 시간에서 이동해야하기 때문에 2011-01-31에서 실제로 때문에 아무것도2011-01-31 00:00:00 ~ 2011-01-31 23:59:59

상한의 경우로 변경할 2011-02-01수 있으며 모든 데이터를2011-01-31 23:59:59

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.