11월에 생성된 모든 행을 가져오기 위해 간단한 쿼리를 실행하려고 합니다:
SELECT COUNT(*)
FROM dbo.profile
WHERE [Created] BETWEEN '2014-11-01 00:00:00.000'
AND '2014-11-30 23:59:59.997';
SMSS가 반환됩니다:
varchar 데이터 유형을 날짜/시간 데이터 유형으로 변환한 결과 범위를 벗어난 값입니다.
Created(생성됨)가 날짜/시간으로 설정되어 있는데 왜 데이터가 varchar에서 날짜/시간으로 변환되는지 이해할 수 없습니다:
서버에 'Created'가 날짜/시간이라고 알려야 하나요? 그렇지 않다면 왜 이 바이트열 메시지가 표시되나요?
편집: 데이터베이스의 값은 YYYY-MM-DD
입니다. 아래 @SqlZim의 답변에 따르면 convert()를 사용하여 데이터베이스의 날짜 형식을 sql에 알려주고 공백 문자를 문자 T로 바꿔야 한다고 합니다:
select count(*)
from dbo.profile
where [created] between convert(datetime,'2014-11-01T00:00:00.000')
and convert(datetime,'2014-11-30T23:59:59.997');`
회원님의 프로필을 확인해보니 영국에 거주하시는 것으로 확인되었습니다. SQL 서버가 날짜 형식 dmy를 사용하도록 설정되어 있다면 문제가 설명됩니다. 날짜/시간 문자열에 공백 대신 'T'를 사용하지 않으면 Sql Server가 이를 ISO8601 형식으로 인식하지 못합니다.
이렇게 해보세요:
select count(*)
from dbo.profile
where [created] between convert(datetime,'2014-11-01T00:00:00.000')
and convert(datetime,'2014-11-30T23:59:59.997');
날짜 및/또는 날짜/시간을 사용하여 쿼리하는 것은 까다로울 수 있으므로 원하는 결과를 얻으려면 이 글을 읽어보시기 바랍니다:
편집 : 오류 메시지에서 범위를 벗어난 값을 명확히하기 위해 월을 30으로 해석하고 날짜를 11로 해석하는 것입니다.
'생성됨'이 날짜/시간으로 설정되어 있는데 왜 데이터가 varchar에서 날짜/시간으로 변환되는지 이해가 안 됩니다.
Created열과 비교하기 위해 제공하는 리터럴은 문자열입니다. 이러한 리터럴을
datetime열과 비교하기 위해 SQL Server는 [데이터 유형 우선 순위][1]의 규칙에 따라 문자열을
datetime` 유형으로 변환하려고 시도합니다. 문자열 형식에 대한 명시적인 정보가 없으면 SQL Server는 문자열을 날짜 시간으로 해석하기 위해 복잡한 규칙을 따릅니다.
제 생각에 이러한 유형의 문제를 피하는 가장 깔끔한 방법은 유형에 대해 명시하는 것입니다. SQL Server는 이를 위해 CAST 및 CONVERT
함수를 제공합니다. 문자열 및 날짜/시간 유형으로 작업할 때는 문자열 형식을 명시적으로 정의할 수 있는 스타일 매개 변수를 제공하기 때문에 CONVERT
를 사용하는 것이 좋습니다.
이 질문에서는 ODBC 표준(밀리초 포함) 형식(스타일 121)의 문자열을 사용합니다. 데이터 유형 및 문자열 스타일을 명시하면 다음과 같은 결과가 나타납니다:
SELECT COUNT(*)
FROM dbo.profile
WHERE [Created] BETWEEN
CONVERT(datetime, '2014-11-01 00:00:00.000', 121)
AND
CONVERT(datetime, '2014-11-30 23:59:59.997', 121);
즉, BETWEEN
대신 반개방 범위를 사용해야 하는 좋은 이유(Aaron이 그의 답변에서 지적한 것처럼)가 있습니다(저는 다양성을 위해 아래 스타일 120을 사용합니다):
SELECT COUNT(*)
FROM dbo.profile
WHERE
[Created] >= CONVERT(datetime, '2014-11-01 00:00:00', 120)
AND [Created] < CONVERT(datetime, '2014-12-01 00:00:00', 120);
유형에 대해 명시하는 것은 특히 날짜와 시간을 다룰 때 매우 좋은 습관입니다.
'사이'는 다른 날짜/시간 유형의 반올림 및 기타 문제로 인해 매우 문제가 많고](http://sqlblog.com/blogs/aaron_bertrand/archive/2011/10/19/what-do-between-and-the-devil-have-in-common.aspx), YYYY-MM-DD
는 어색한 T
가 없는 안전한 형식이 아니므로, 구분 기호 없이 ISO 표준 전체 날짜를 사용하는 개방형 범위가 훨씬 더 나은 접근 방식입니다:
WHERE Created >= '20141101' AND Created < '20141201';