특정 월의 모든 레코드를 찾는 WHERE 절


87

저장 프로 시저에 월과 연도를 부여하고 그 달에 발생한 모든 일을 반환하도록하고 싶습니다. 어떤 달에는 일 수가 다르기 때문에 비교할 수 없기 때문에 어떻게해야합니까?

이를 수행하는 가장 좋은 방법은 무엇입니까? 연도와 월을 기준으로 비교를 요청할 수 있습니까?

감사.

답변:


186

나는 당신이 찾고있는 기능이라고 생각합니다 MONTH(date). 'YEAR' 도 사용하고 싶을 것입니다 .

다음 things과 같은 이름의 테이블이 있다고 가정 해 보겠습니다 .

id happend_at
-- ----------------
1  2009-01-01 12:08
2  2009-02-01 12:00
3  2009-01-12 09:40
4  2009-01-29 17:55

happened_at2009/01 월 (2009 년 1 월) 동안 a가있는 모든 레코드를 찾기 위해 실행하려고한다고 가정 해 보겠습니다 . SQL 쿼리는 다음과 같습니다.

SELECT id FROM things 
   WHERE MONTH(happened_at) = 1 AND YEAR(happened_at) = 2009

다음을 반환합니다.

id
---
1
3
4

14
과연! "DAY, MONTH 및 YEAR 함수는 각각 DATEPART (dd, date), DATEPART (mm, date) 및 DATEPART (yy, date)의 동의어입니다."
Tarks

17

대부분의 응답에서 제안 된대로 MONTH 및 YEAR 함수를 사용하면 SQL Server가 날짜 열에있을 수있는 인덱스를 사용할 수 없다는 단점이 있습니다. 이것은 큰 테이블에서 성능을 저하시킬 수 있습니다.

관심있는 달의 첫 번째 날을 나타내는 저장 프로 시저에 DATETIME 값 (예 : @StartDate)을 전달하고 싶습니다.

그런 다음 사용할 수 있습니다.

SELECT ... FROM ...
WHERE DateColumn >= @StartDate 
AND DateColumn < DATEADD(month, 1, @StartDate)

저장 프로 시저에 별도의 매개 변수로 월과 연도를 전달해야하는 경우 CAST 및 CONVERT를 사용하여 월의 첫 번째 날을 나타내는 DATETIME을 생성 한 다음 위와 같이 진행할 수 있습니다. 이렇게하면 정수 연도, 월, 일 값에서 DATETIME을 생성하는 함수를 작성하는 것이 좋습니다. 예를 들어 SQL Server 블로그 의 다음과 같습니다 .

create function Date(@Year int, @Month int, @Day int)
returns datetime
as
    begin
    return dateadd(month,((@Year-1900)*12)+@Month-1,@Day-1)
    end
go

그러면 쿼리는 다음과 같이됩니다.

SELECT ... FROM ...
WHERE DateColumn >= Date(@Year,@Month,1)
AND DateColumn < DATEADD(month, 1, Date(@Year,@Month,1))

1
Ya 저는 @joe에 동의합니다. "대부분의 응답에서 제안 된대로 MONTH 및 YEAR 함수를 사용하면 SQL Server가 날짜 열에있는 인덱스를 사용할 수 없다는 단점이 있습니다. 이로 인해 큰 테이블에서 성능이 저하 될 수 있습니다. . "
Raghav 2009-08-26

뭔가 추가해도 될까요? 매개 변수에서 '@StartDate를 선언하는 경우 SQL이 각 행에 대해 계산을 수행하지 않고'@EndDate를 선언하고 DATEADD를 거기에 배치합니다.
DataGirl

@DataGirl-흥미로운 점. DATEADD 함수가 런타임 상수로 처리되고 한 번만 평가 될 것이라고 가정했습니다. 이것에 대해 의심이가는 경우 선언 @EndDate하면 명시 적으로 표시됩니다.
Joe

4

더 많은 팁이 매우 간단합니다. to_char 함수를 사용할 수도 있습니다 .

한 달 동안 :

to_char (happened_at, 'MM') = 01

년 동안 :
to_char (happened_at, 'YYYY') = 2009

하루 동안 :

to_char (happened_at, 'DD') = 01

to_char 함수는 하나의 특정 데이터베이스가 아닌 SQL 언어로 지원됩니다.

더 많은 사람을 돕길 바랍니다 ...

복근!


1
저는 이것이 Oracle에서만 작동한다는 인상을 받았습니다. 정말 구체적입니다. SQL Server는 확실히 그것을 지원하지 않습니다.
Carol

3

MONTH 및 YEAR 함수의 대안으로 일반 WHERE 절도 작동합니다.

select *
from yourtable
where '2009-01-01' <= datecolumn and datecolumn < '2009-02-01'


1

연도와 월을 기준으로 비교를 요청할 수 있습니까?

할 수 있습니다. 다음은 AdventureWorks 샘플 데이터베이스를 사용하는 간단한 예입니다.

DECLARE @Year       INT
DECLARE @Month      INT

SET @Year = 2002
SET @Month = 6

SELECT 
    [pch].* 
FROM 
    [Production].[ProductCostHistory]   pch
WHERE
    YEAR([pch].[ModifiedDate]) = @Year
AND MONTH([pch].[ModifiedDate]) = @Month

1

나는 쉽게 (예 : 시간 데이터 형식으로 값을 전달 찾을 DATETIME후 특히, 시간 기능을 사용) DATEADDDATEPART이 경우에 달이 발견을 시작 날짜와 종료 날짜 쌍을 예, 기간의 시작 및 종료 날짜를 찾기 위해, 이번 달의 경우 CURRENT_TIMESTAMP매개 변수 유형으로 대체 DATETIME하십시오 (1990-01-01 값은 완전히 임의적 임).

SELECT DATEADD(M, 
          DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP), 
          '1990-01-01T00:00:00.000'), 
       DATEADD(M, 
          DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP), 
          '1990-01-31T23:59:59.997')

0

다음과 같이해야합니다.

select * from yourtable where datepart(month,field) = @month and datepart(year,field) = @year

또는 레코드를 만들 때 월과 연도를 고유 한 열로 분할 한 다음 이에 대해 선택할 수 있습니다.

Iain


0

한 가지 방법은 월의 첫 번째를 나타내는 변수를 만드는 것입니다 (예 : 2009 년 5 월 1 일), proc에 전달하거나 빌드 (월 / 1 년 연결). 그런 다음 DateDiff 함수를 사용합니다.

WHERE DateDiff(m,@Date,DateField) = 0

이것은 월과 연도가 일치하는 모든 것을 반환합니다.


-4
SELECT * FROM yourtable WHERE yourtimestampfield LIKE 'AAAA-MM%';

AAAA원하는 연도와 MM원하는 달은 어디에 있습니까?

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