날짜 시간 열에서 날짜를 선택하는 방법은 무엇입니까?


238

2009-10-20 10:00:00과 같은 값을 가진 "datetime"유형의 열이 있습니다.

datetime에서 날짜를 추출하고 다음과 같은 쿼리를 작성하고 싶습니다.

SELECT * FROM 
data 
WHERE datetime = '2009-10-20' 
ORDER BY datetime DESC

다음이 가장 좋은 방법입니까?

SELECT * FROM 
data 
WHERE datetime BETWEEN('2009-10-20 00:00:00' AND '2009-10-20 23:59:59')
ORDER BY datetime DESC

그러나 이것은 빈 결과 집합을 반환합니다. 어떤 제안?

답변:


456

MySQL의 DATE()기능을 사용할 수 있습니다 :

WHERE DATE(datetime) = '2009-10-20'

당신은 또한 이것을 시도 할 수 있습니다 :

WHERE datetime LIKE '2009-10-20%'

의 성능 영향에 대한 정보는 이 답변 을 참조하십시오 LIKE.


2
이것을 시도 : DATE (datetime) = '2009-10-20', 그것은 작동합니다
mysqllearner

44
첫 번째는 매우 느리고 인덱스를 무시합니다. 'date %'와 같이하는 것이 좋습니다
kachar

'% keyword %'와 같은 날짜 (날짜 / 시간)의 작동 방식, 감사
silvia zulinka

2
Rails 시간대가 UTC가 아닌 경우 예상대로 작동하지 않는다고 생각합니다. DATE ()가 열 값을 UTC로 해석하기 때문입니다. 따라서 "2016-12-30"에 대해 문의 한 경우 "2016 년 12 월 30 일 금요일 00:00:00 SGT +08 : 00"와 같은 날짜는 찾을 수 없습니다. 왜? DATE ()는 비교를 수행하기 전에 "2016-12-29 16:00:00 UTC"로 UTC와 동등한 것으로 해석하기 때문입니다. 최근까지 나에게도 문제가 되었기 때문에 내가 틀렸다면 정정하십시오.
Tikiboy

WHERE DATE (datetime) = '{? sdate}는 Crystal Reports 매개 변수에 완벽하게 작동합니다! 잘 하셨어요!
MikeMighty

94

사용 WHERE DATE(datetime) = '2009-10-20' 에 성능 문제가 있습니다 . 여기에 명시된 바와 같이 :

  • DATE()일치하지 않는 행을 포함하여 모든 행에 대해 계산 합니다.
  • 쿼리에 인덱스를 사용하는 것은 불가능합니다.

사용 BETWEEN하거나 >, <, =인덱스를 사용할 수 있도록 운영자 :

SELECT * FROM data 
WHERE datetime BETWEEN '2009-10-20 00:00:00' AND '2009-10-20 23:59:59'

업데이트 : 인덱싱 된 열에서 연산자 대신 사용에 대한 영향 이 높습니다 . 다음은 1,176,000 개의 행이있는 테이블에 대한 테스트 결과입니다.LIKE

  • 사용 datetime LIKE '2009-10-20%'=> 2931ms
  • 사용 datetime >= '2009-10-20 00:00:00' AND datetime <= '2009-10-20 23:59:59'=> 168ms

동일한 쿼리에 대해 두 번째 호출을 수행하면 차이가 훨씬 높아집니다. 2984ms 대 7ms (예, 7 밀리 초) Hibernate를 사용하여 프로젝트에서 오래된 코드를 다시 쓰는 동안 이것을 발견했습니다.


흥미롭게도 MySql 구현 이 장면 DATE(datetime)을 자동으로 변환 하도록 변환 BETWEEN AND 하면 짧은 문장과 멋진 성능을 얻습니다. 왜 안돼? 왜 그들이 이것을하지 않았습니까? :)
Cherry

같은 것이 DATE(datetime) in (:list)작동하지 않기 때문에BETWEEN
Tim

25

날짜 시간을 YMD 부분으로 형식화 할 수 있습니다.

DATE_FORMAT(datetime, '%Y-%m-%d')

2
이 방법으로 필요한 경우 시간 부분 만 얻을 수 있습니다.DATE_FORMAT(datetime, '%H:%i:%S')
Metafaniel

이것은 날짜 시간 형식을 지정하는 데 효과적이지만 대신 데이터베이스는 새 배열을 반환하여 이름을 DATE_FORMAT (columnName, '% Y- % m- % d') arrayName 끝에 원하는 이름으로 설정합니다. 자세한 내용은 확인하십시오. 문서화는 dev.mysql.com/doc/refman/8.0/en/...
리다 Rezzag에게

15

페이지의 모든 답변이 원하는 결과를 반환하지만 모두 성능 문제가 있습니다. 절의 필드에서 계산을 수행하지 마십시오 WHERE(DATE()테이블의 모든 행에서 계산을 수행해야하므로 계산 .

BETWEEN ... AND구문은 두 국경 조건에 모두 포함되며 다른 날짜가있는 종료 날짜에 23:59:59 구문을 지정해야합니다 (마이크로 초 트랜잭션, 질문은 2009 년에 MySQL이 지원하지 않았다고 생각합니다).

timestamp특정 날짜에 대해 MySQL 필드 를 쿼리하는 올바른 방법 은 원하는 날짜에 대해 Greater-Than-Equals를 확인하고 시간을 지정하지 않고 그 다음 날에 Less-Than을 확인하는 것입니다.

WHERE datetime>='2009-10-20' AND datetime<'2009-10-21'

이 방법은 성능이 가장 빠르고 메모리가 가장 적고 리소스가 가장 적은 방법이며 초 단위 시간 소인 정밀도와 같은 모든 MySQL 기능 및 코너 케이스를 추가로 지원합니다. 또한 미래의 증거입니다.


1
그리고 성능 인수를 사용하여 "> ="및 "<"가 테이블의 각 행에서 동일하게 계산됩니까, 아니면 SQL 서버가 숫자가 다른 것보다 큰지를 "마 법적으로"알고 있습니까? :-)
Javier Guerrero

@ JavierGuerrero : 내 예제는 두 개의 상수를 비교합니다 : 하나는 테이블과 문자열 리터럴입니다.
dotancohen

"테이블에서 하나"는 상수가 아니며 각 행마다 다르므로 각 행에 대해 동일한 계산을 수행해야합니다 (또한 비교를 수행하려면 에포크 시간으로 변환해야 함)
Javier Guerrero

9

모든 형식은 다음과 같습니다

이것이 datetimetable 값 을 포함하는 열이라고 가정 하십시오 data.

+--------------------+
| date_created       |
+--------------------+
| 2018-06-02 15:50:30|
+--------------------+

mysql> select DATE(date_created) from data;
+--------------------+
| DATE(date_created) |
+--------------------+
| 2018-06-02         |
+--------------------+

mysql> select YEAR(date_created) from data;
+--------------------+
| YEAR(date_created) |
+--------------------+
|               2018 |
+--------------------+

mysql> select MONTH(date_created) from data;
+---------------------+
| MONTH(date_created) |
+---------------------+
|                   6 |
+---------------------+

mysql> select DAY(date_created) from data;
+-------------------+
| DAY(date_created) |
+-------------------+
|                 2 |
+-------------------+

mysql> select HOUR(date_created) from data;
+--------------------+
| HOUR(date_created) |
+--------------------+
|                 15 |
+--------------------+

mysql> select MINUTE(date_created) from data;
+----------------------+
| MINUTE(date_created) |
+----------------------+
|                   50 |
+----------------------+

mysql> select SECOND(date_created) from data;
+----------------------+
| SECOND(date_created) |
+----------------------+
|                   31 |
+----------------------+

5

당신이 사용할 수있는:

DATEDIFF ( day , startdate , enddate ) = 0

또는:

DATEPART( day, startdate ) = DATEPART(day, enddate)
AND 
DATEPART( month, startdate ) = DATEPART(month, enddate)
AND
DATEPART( year, startdate ) = DATEPART(year, enddate)

또는:

CONVERT(DATETIME,CONVERT(VARCHAR(12), startdate, 105)) = CONVERT(DATETIME,CONVERT(VARCHAR(12), enddate, 105))

5

날짜 함수를 사용하는 간단하고 가장 좋은 방법

SELECT * FROM 
data 
WHERE date(datetime) = '2009-10-20' 

또는

SELECT * FROM 
data 
WHERE date(datetime ) >=   '2009-10-20'  && date(datetime )  <= '2009-10-20'

-5

음, 사용 LIKE성명은 최선의 선택 WHERE datetime LIKE '2009-10-20%' 이이 경우에 작동합니다

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