본문 바로가기
IT/MSSQL

MSSQL DATETIME 날짜 기간 검색

by ^&**&^ 2023. 6. 23.
반응형

 


1. 가장 기본적인 날짜 검색 쿼리 

 

1
SAMPLE_DATETIME >= '2023-03-01' AND SAMPLE_DATETIME <= '2023-03-03'
cs


이렇게 조회하면 2023-03-01 00:00:00 ~ 2023-03-03 00:00:00까지 조회됩니다. 

 


2. 성능을 조금 개선한 쿼리(BETWEEN 사용) - 아주 조금 빨라짐

 

1
SAMPLE_DATETIME BETWEEN '2023-03-01' AND '2023-03-03'
cs

 

 

3. 2번 쿼리는 MSSQL Server 내부적으로 아래의 쿼리로 변경됩니다. 

 

1
SAMPLE_DATETIME BETWEEN CONVERT(DATETIME'2023-03-01 00:00:00.000'
AND CONVERT(DATETIME'2023-03-03 00:00:00.000')
 

따라서 1,2,3번 쿼리는 조회의 마지막 일자에 대해 정확하게 조회되지 않는 단점이 있습니다. 

 


4. 그래서 조회 기간의 끝의 시분초를 지정해줘야 합니다. (비추하는 방식)


   아래의 쿼리처럼 AND 다음에 23:59:59.999 지정을 해줘야죠. 이 방법은 시분초까지 작성해야 하기 때문에 번거롭고 손이 많이 타네요. 

 

1
SAMPLE_DATETIME BETWEEN CONVERT(DATETIME'2023-03-01 00:00:00.000'
AND CONVERT(DATETIME'2023-03-03 23:59:59.999')
cs

 

 

5. 4번 쿼리와 동일한 결과와 성능을 가지지만 날짜 문자열만으로 처리 


   DATEADD 함수를 사용하여 처리하는 방법입니다. 
   성능적으로 4번가 거의 차이가 없습니다. 차이가 미미하죠. 

 

1
2
SAMPLE_DATETIME BETWEEN CONVERT(DATETIME'2023-03-01'
AND DATEADD(MILLISECOND, -10, DATEADD(DAY, 1, CONVERT(DATETIME'2023-03-03')))
 
cs



결론적으로 가장 편리한 방법은 아래의 쿼리입니다. 

 

1
SAMPLE_DATETIME BETWEEN '2023-03-01' 
AND DATEADD(DAY, 1, CONVERT(DATETIME'2023-03-03'))
cs

 

시작일자는 그대로 사용하고 종료일자만 형변환을 작성하는 방법이죠.

이렇게 작성되면 범위가 2023-03-01 00:00:00 ~ 2023-03:04 00:00:00 이렇게 되기 때문에 4일 00:00:00.000 도 포함됩니다. 
이 정도는 문제 되지 않는다면 위 방법이 가장 편리하면서도 간단한 방법이 됩니다. 

 

다시 성능상의 관점으로 아래의 쿼리에 대해 수행시간을 살펴보면 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- 1. DATEADD 로 날짜 처리
SELECT *
  FROM SAMPLE_TABLE AS A WITH(NOLOCK)
 WHERE 1=1
   AND SAMPLE_DATETIME BETWEEN DATEADD(DAY, -DAY(GETDATE()) + 1, GETDATE())  -- 달의 1일
                           AND DATEADD(MONTH, 1, GETDATE()) - DAY(GETDATE()); -- 달의 말일
;
 
-- 2. 바로 날짜값으로 처리 
SELECT *
  FROM SAMPLE_TABLE AS A WITH(NOLOCK)
 WHERE 1=1
   AND SAMPLE_DATETIME BETWEEN CAST('2023-04-01 00:00:00' AS DATETIME
                           AND CAST('2023-04-30 11:59:59' AS DATETIME)
;
 
cs

 

(2)번이 조금이나마 성능이 좋습니다. 그냥 자료형 바로 조회하는 것이 제일 좋은 방식인 거죠. 

 



추가적으로 날짜형 데이터를 문자형으로 비교하는 방법은 사용하지 않는 것을 추천드립니다. 

아래의 방법으로 조회하는 쿼리이죠. 

 

1
CONVERT(VARCHAR, SAMPLE_DATETIME, 102) BETWEEN '2023.03.06' 
AND '2023.03.09'
cs


이 방법은 성능상 날짜형 자체를 비교하는 것과 비교할 수 없는 성능의 차이를 가지고 옵니다. 
그냥 성능은 포기하는 방법입니다. 


[ 참고 ]

1
2
3
4
5
6
7
SELECT CONVERT(DATETIME'2023-03-01'
-- 2023-03-01 00:00:00.000
 
SELECT DATEADD(MILLISECOND, -1, DATEADD(DAY, 1, CONVERT(DATETIME'2023-03-03')))
-- 2023-03-04 00:00:00.000
 
 
cs

 

또한 DatePart를 사용하는 방법도 별로 추천하지는 않습니다. 날짜형으로 검색할 때 보다는 조금 성능이 떨어지게 되어 있습니다.

 

1
2
3
4
5
6
SELECT *
  FROM TEST_TABLE
 WHERE 1=1
   AND DATEPART(YEAR, MY_DATETIME) = '2023'
   AND DATEPART(MONTH, MY_DATETIME) = '1'
;
cs

 

 

 

반응형

댓글