오늘의 타임 스탬프가있는 행을 선택하는 방법은 무엇입니까?


104

데이터베이스 테이블에서 오늘의 레코드 만 선택하려고합니다.

현재 나는

SELECT * FROM `table` WHERE (`timestamp` > DATE_SUB(now(), INTERVAL 1 DAY));

그러나 이것은 지난 24 시간 동안의 결과를 필요로하며 시간을 무시하고 오늘의 결과 만 선택하는 데 필요합니다. 날짜만을 기준으로 결과를 선택하려면 어떻게해야합니까?

답변:


191

사용 DATECURDATE()

SELECT * FROM `table` WHERE DATE(`timestamp`) = CURDATE()

내가 추측 사용하여 DATE 여전히 INDEX를 사용합니다 .

데모에서 실행 계획보기


차이점을 확인하십시오. SQL-Fiddle 두 번째 쿼리에서 FILTERED = 25를 확인합니다.
ypercubeᵀᴹ

@ypercube 오 나는 그것을 놓쳤지만 왜 여분의 가치가 있는지 궁금합니다 Using where; Using index.
John Woo

1
인덱스는 행을 선택하는 데 사용됩니다. 그러나 쿼리를 사용하여 전체 인덱스를 스캔합니다 (모든 값은 조건을 평가하기 위해 DATE ()로 변환 됨). 더 나은 예로 내 대답을 업데이트하겠습니다.
ypercubeᵀᴹ

1
모든면에서 ypercube 솔루션은 성능상의 이유로 더 좋습니다. 테이블에 수십만 개의 라인이있는 경우 반드시이 방향으로 가야합니다
Vincent

1
은``입니다 중요하기 때문에 timestamp(그리고 date내 경우처럼) MySQL의 예약어입니다
빅터 페레이라

55

인덱스를 사용하고 쿼리가 테이블 스캔을 수행하지 않도록하려는 경우 :

WHERE timestamp >= CURDATE()
  AND timestamp < CURDATE() + INTERVAL 1 DAY

이것이 실제 실행 계획에 미치는 차이를 보여주기 위해 SQL-Fiddle (매우 유용한 사이트)을 사용하여 테스트합니다 .

CREATE TABLE test                            --- simple table
    ( id INT NOT NULL AUTO_INCREMENT
    ,`timestamp` datetime                    --- index timestamp
    , data VARCHAR(100) NOT NULL 
          DEFAULT 'Sample data'
    , PRIMARY KEY (id)
    , INDEX t_IX (`timestamp`, id)
    ) ;

INSERT INTO test
    (`timestamp`)
VALUES
    ('2013-02-08 00:01:12'),
    ---                                      --- insert about 7k rows
    ('2013-02-08 20:01:12') ;

지금 두 가지 버전을 사용해 보겠습니다.


버전 1 DATE(timestamp) = ?

EXPLAIN
SELECT * FROM test 
WHERE DATE(timestamp) = CURDATE()            ---  using DATE(timestamp)
ORDER BY timestamp ;

설명:

ID  SELECT_TYPE  TABLE  TYPE  POSSIBLE_KEYS  KEY  KEY_LEN  REF 
1   SIMPLE       test   ALL

ROWS  FILTERED  EXTRA
6671  100       Using where; Using filesort

그것은 모든 (6671) 행을 필터링 한 후 filesort를 (반환 된 행이 몇 가지로 그 문제가되지 않습니다) 수행


버전 2 timestamp <= ? AND timestamp < ?

EXPLAIN
SELECT * FROM test 
WHERE timestamp >= CURDATE()
  AND timestamp < CURDATE() + INTERVAL 1 DAY
ORDER BY timestamp ;

설명:

ID  SELECT_TYPE  TABLE  TYPE  POSSIBLE_KEYS  KEY  KEY_LEN  REF 
1   SIMPLE       test   range t_IX           t_IX    9 

ROWS  FILTERED  EXTRA
2     100       Using where

그것은 사용하는 인덱스의 범위를 스캔 한 다음 테이블 만 대응 행을 판독한다.


sql-fiddle에 대한 훌륭한 설명과 감사합니다. 잠시 나를 던진 스키마에 대한 하나의 댓글 은 기본 키가 색인에 암시되어 INDEX t_IX (timestamp, id)있으므로 INDEX t_IX (timestamp)일 수 있습니다 (해야합니까?) . 아니면 내가 이해하지 못하는 이유가 있습니까? 나는 sql-fiddle에서 그것을 시도하고 동일한 (더 나은) 실행 계획을 보았다
natbro

1
@natbro 예, 테이블이 InnoDB 엔진을 사용하는 경우 id(PK이므로 테이블의 클러스터형 인덱스이기 때문에) 어쨌든 인덱스에 추가됩니다. 따라서 명시 적으로 추가해도 문제가되지 않습니다 (그리고 일부 옵티 마이저 사각 지대를 잡을 수 있습니다). 이 경우 / 쿼리에서는 확실히 관련이 없습니다.
ypercubeᵀᴹ

timestamp < CURDATE() + INTERVAL 1 DAY필요한지 설명 할 수 있습니까 ?
Nightwolf

@Nightwolf는 타임 스탬프 값이 미래인 곳에 행이 저장되어있을 수 있기 때문입니다. 질문은 "오늘의 기록 만"을 요구합니다 .
ypercubeᵀᴹ

@ TypoCubeᵀᴹ Aha, 타임 스탬프가 미래 날짜를 표시하지 않기 때문에 순전히 고려하지 않았습니다. 그럼에도 불구하고 명심해야 할 좋은 점입니다.
Nightwolf

11
SELECT * FROM `table` WHERE timestamp >= CURDATE()

더 짧고 'AND timestamp <CURDATE () + INTERVAL 1 DAY'를 사용할 필요가 없습니다.

CURDATE ()는 항상 현재 날짜를 반환하기 때문입니다.

MySQL CURDATE () 함수


a) 질문은 "오늘의 레코드 만"을 요구하며 코드는 미래 날짜도 가져옵니다. b) 비교가 작동하지 않습니다. DATE (timestamp)로 비교해야합니다. 즉, 답변을 수정하면 @JohnWoo 원래 답변을 얻을 수 있습니다.
Katapofatico

2

이 고양이를 얼마나 많은 방법으로 피부를 벗길 수 있습니까? 여기에 또 다른 변형이 있습니다.

SELECT * FROM tableWHERE DATE (FROM_UNIXTIME ( timestamp)) = '2015-11-18';


2

특정 날짜와 비교하려면 다음과 같이 직접 작성할 수 있습니다.

select * from `table_name` where timestamp >= '2018-07-07';

// 여기서 타임 스탬프는 유형이 타임 스탬프 인 열의 이름입니다.

또는

오늘 날짜를 가져 오려면 CURDATE () 함수를 사용할 수 있습니다.

select * from `table_name` where timestamp >=  CURDATE();

1

간단히 날짜로 캐스트하십시오.

SELECT * FROM `table` WHERE CAST(`timestamp` TO DATE) == CAST(NOW() TO DATE)

1

이것은 내 의견으로는 가장 쉬울 수 있습니다.

SELECT * FROM `table` WHERE `timestamp` like concat(CURDATE(),'%');


0

Visual Studio 2017에서 개발을 위해 기본 제공 데이터베이스를 사용하여 현재 주어진 솔루션에 문제가 있었는데 DATE ()가 기본 제공 함수가 아니라는 오류가 발생했기 때문에 작동하도록 코드를 변경해야했습니다.

내 해결책은 다음과 같습니다.

where CAST(TimeCalled AS DATE) = CAST(GETDATE() AS DATE)


아마도 MySQL이 아니라 다른 DBMS (SQL Server일까요?)를 사용하고 있었을 것입니다. 질문의 태그를 확인하십시오.
ypercubeᵀᴹ
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.