MySQL은 DATE 문자열을 DATETIME 필드의 문자열과 비교합니다.


93

질문이 있습니다. 하나의 DATE 문자열 "2010-04-29"를 DATETIME (2010-04-29 10:00)으로 저장된 문자열과 비교하여 MySQL 데이터베이스에서 선택할 수 있습니까?

데이터를 필터링하는 날짜 선택기가 하나 있고 다음과 같이 DATETIME 필드로 테이블을 쿼리하고 싶습니다.

SELECT * FROM `calendar` WHERE startTime = '2010-04-29'"

... 그리고 DATETIME 값이 "2010-04-29 10:00"인 행을 가져오고 싶습니다.

어떤 제안? 감사.

답변:


163

다음을 사용하십시오.

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'

참고로 2 백만 개의 레코드 테이블이 있는데 비슷한 쿼리를 실행했습니다. Salils 답변은 4.48 초, 위의 답변은 2.25 초가 걸렸습니다.

따라서 테이블이 BIG라면 오히려 이것을 제안 할 것입니다.


8
첫 번째 대답은 비교하기 전에 각 datetime을 문자열로 형식화해야하기 때문에 너무 느립니다. 필드의 날짜 부분 만 직접 비교하지만 여전히 인덱스를 사용할 수 없기 때문에 더 좋습니다 (mysql 5.1에서 테스트 됨)
Marki555

1
성능이 문제인 경우 날짜 및 시간 부분을 별도로 저장하여 INDEX를 날짜 부분에 배치 할 수 있습니다.
Thijs Riezebeek 2015

1
이 쿼리 startTime는 인덱싱 된 경우 인덱스를 사용할 수 없습니다 .
Zamrony P. Juhara

43

DATETIME 열의 DATE 부분이 특정 리터럴과 일치하는 모든 행을 선택하려면 다음과 같이 할 수 없습니다.

WHERE startTime = '2010-04-29'

MySQL은 DATE와 DATETIME을 직접 비교할 수 없기 때문입니다. MySQL이하는 일은 주어진 DATE 리터럴을 시간 '00 : 00 : 00 '으로 확장합니다. 그래서 당신의 상태는

WHERE startTime = '2010-04-29 00:00:00'

확실히 당신이 원하는 것이 아닙니다!

조건은 범위이므로 범위로 지정해야합니다. 몇 가지 가능성이 있습니다.

WHERE startTime BETWEEN '2010-04-29 00:00:00' AND '2010-04-29 23:59:59'
WHERE startTime >= '2010-04-29' AND startTime < ('2010-04-29' + INTERVAL 1 DAY)

DATETIME 열이 1 초 미만의 해상도를 사용하고 23:59:59 + 엡실론에 약속이있는 경우 첫 번째 오류가 발생할 가능성이 거의 없습니다. 일반적으로 두 번째 변형을 사용하는 것이 좋습니다.

두 변형 모두 테이블이 커질 때 중요 해지는 startTime의 인덱스를 사용할 수 있습니다.


9
David의 버전은 좋지 않으며 색인을 사용할 수 없습니다. 인덱스를 사용하려면, 당신은하지 함수 (결과에 직접 열을 필터에이 date(), year(), datediff()또는 유사한)
Marki555

나는 mysql이 날짜를 datetime으로 변환하는 방법을 찾고 있었다 00:00:00. 이제 내 결과가 의미가 있습니다
Accountant م

1
이것은 가능한 경우 인덱스를 사용할 수없는 다른 답변에 비해 정확한 빠른 솔루션입니다
Zamrony P. Juhara dec.

23
SELECT * FROM `calendar` WHERE DATE_FORMAT(startTime, "%Y-%m-%d") = '2010-04-29'"

또는

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'

25
이것은 끔찍한 쿼리입니다. 어떤 대가를 치르더라도 이것을 피하십시오. startTime에 인덱스가 있으면 직접 사용하지 않고 열에 함수를 적용하므로이 쿼리에서 사용할 수 없습니다. 즉, 이와 같은 쿼리에는 전체 테이블 스캔이 필요합니다. 큰 테이블에서 이것은 매우 느린 쿼리를 의미합니다.
steveayre 2013 년

동의합니다. 그의 대답은 틀 렸습니다. 정답은 David가 아래에 게시했습니다.
mindplay.dk jul.

1
더 빠르기 때문에 David의 답변을 사용하십시오. 이 사람은 ... 유효하지만 속도에 대한 좋지 않다
xarlymg89

1
@ CarlosAlbertoMartínezGadea이 버전은 비교하기 전에 각 값의 형식을 문자열로 지정해야하기 때문에 느립니다. David의 버전에는 필요하지 않지만 여전히 인덱스를 사용할 수 없으므로 최적이 아닙니다. 인덱스를 사용할 수있는 버전은 XL_의 답변을 참조하십시오. 불행히도 mysql에서 제대로 수행하는 더 좋은 방법은 없습니다
Marki555

1
쿼리는 인덱스를 사용할 수 없지만 @XL_의 대답은 사용하기 때문에이 대답을 반대표를 던졌습니다.
pedromanoel 2014-06-11

2
SELECT * FROM sample_table WHERE last_visit = DATE_FORMAT('2014-11-24 10:48:09','%Y-%m-%d %H:%i:%s')

이것은 mysql에서 DATE_FORMAT(date,format).


1
SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29';

도움이되며 DATE비교하기 전에 값을 변환 할 수 있습니다 .


0

DATETIME 필드를 다음과 같이 DATE로 캐스트 할 수 있습니다.

SELECT * FROM `calendar` WHERE CAST(startTime AS DATE) = '2010-04-29'

이것은 매우 효율적입니다.


1
아니 그것도 효율적이지 않습니다. 경우이 인덱스를 사용할 수 없습니다 startTime색인
Zamrony P. Juhara을

-6
SELECT * FROM `calendar` WHERE startTime like '2010-04-29%'

이후 또는 이전에 무언가를 찾으려면 MySQL 날짜에 비교 연산자를 사용할 수도 있습니다. 이는 단순한 문자열 정렬이 올바르게 정렬하는 방식 (가장 큰 값에서 가장 작은 값에서 가장 작은 것까지 선행 0)으로 작성되기 때문입니다.

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