SQL 서버에서 지난달의 기록 가져 오기
내 db 테이블 [member] 필드 "date_created"를 기반으로 지난 달의 레코드를 얻고 싶습니다.
이 작업을 수행하는 SQL은 무엇입니까?
설명을 위해 지난 달-2009 년 8 월 8 일 ~ 2009 년 8 월 31 일
오늘이 2010 년 3 월 1 일인 경우 2009 년 1 월 2 일부터 2009 년 12 월 31 일까지의 기록을 가져와야합니다.
SELECT *
FROM Member
WHERE DATEPART(m, date_created) = DATEPART(m, DATEADD(m, -1, getdate()))
AND DATEPART(yyyy, date_created) = DATEPART(yyyy, DATEADD(m, -1, getdate()))
월과 연도를 확인해야합니다.
모든 기존 (작동하는) 답변에는 두 가지 문제 중 하나가 있습니다.
- 검색중인 열의 색인을 무시합니다.
- 의지 (잠재적으로)는 의도하지 않은 데이터를 선택하여 결과를 자동으로 손상시킵니다.
1. 무시 된 지표 :
대부분의 경우 검색중인 열에 호출 된 함수가있을 때 (암시 적으로 for와 같은 포함 CAST
) 옵티마이 저는 열의 인덱스를 무시하고 모든 레코드를 검색해야합니다. 다음은 간단한 예입니다.
우리는 타임 스탬프를 다루고 있으며, 대부분의 RDBMS는이 정보를 일종의 증가하는 값 (보통 밀리 / 나노초 long
또는 BIGINTEGER
수) 으로 저장하는 경향이 있습니다 . 따라서 현재 시간은 다음과 같이 표시 / 저장됩니다.
1402401635000000 -- 2014-06-10 12:00:35.000000 GMT
'2014'
거기에 '년'값 ( ) 이 보이지 않습니까? 사실, 앞뒤로 번역하는 데 약간의 복잡한 수학이 있습니다. 따라서 검색된 열에서 추출 / 날짜 부분 함수를 호출하는 경우 서버는 결과에 포함 할 수 있는지 알아 내기 위해 모든 수학을 수행해야합니다. 작은 테이블에서 이것은 문제가되지 않지만 선택된 행의 비율이 감소함에 따라 더 크고 더 큰 드레인이됩니다. 그런 다음이 경우에 대해 질문하기 위해 두 번째로하고 있습니다 MONTH
. 음, 그림을 얻습니다.
2. 의도하지 않은 데이터 :
특정 SQL 서버의 버전 및 컬럼 데이터 유형, 사용에 따라 BETWEEN
(또는 유사한 포괄적 상한선 범위 : <=
) 할 수있는 잘못된 데이터 결과가 선택되고 . 기본적으로 잠재적으로 "다음"날 자정의 데이터를 포함하거나 "현재"날짜의 레코드 일부를 제외하게됩니다.
당신은 무엇을 해야 하고 수 :
따라서 데이터에 대해 안전한 방법이 필요하고 (가능한 경우) 인덱스를 사용할 것입니다. 올바른 방법은 다음과 같은 형식입니다.
WHERE date_created >= @startOfPreviousMonth AND date_created < @startOfCurrentMonth
한 달만 있다는 점을 감안할 때 다음 @startOfPreviousMonth
으로 쉽게 대체 / 파생 할 수 있습니다.
DATEADD(month, -1, @startOCurrentfMonth)
서버에서 현재 월의 시작을 유도해야하는 경우 다음을 통해 수행 할 수 있습니다.
DATEADD(month, DATEDIFF(month, 0, CURRENT_TIMESTAMP), 0)
여기에 간단한 설명이 있습니다. 이니셜 DATEDIFF(...)
은 현재 시대의 시작 ( 0001-01-01
-AD, CE 등) 사이의 차이를 가져와 본질적으로 큰 정수를 반환합니다. 이것은 현재 달 의 시작까지의 개월 수입니다 . 그런 다음이 숫자를 해당 월의 시작 인 시대의 시작에 추가합니다.
따라서 전체 스크립트는 다음과 비슷하게 보일 수 있습니다.
DECLARE @startOfCurrentMonth DATETIME
SET @startOfCurrentMonth = DATEADD(month, DATEDIFF(month, 0, CURRENT_TIMESTAMP), 0)
SELECT *
FROM Member
WHERE date_created >= DATEADD(month, -1, @startOfCurrentMonth) -- this was originally misspelled
AND date_created < @startOfCurrentMonth
따라서 모든 날짜 작업은 하나의 값에 대해 한 번만 수행됩니다. 옵티마이 저는 인덱스를 자유롭게 사용할 수 있으며 잘못된 데이터가 포함되지 않습니다.
지금까지 제공된 옵션을 추가하면 색인을 전혀 사용하지 않습니다.
이와 같은 것이 트릭을 수행하고 테이블의 인덱스를 사용합니다 (존재하는 경우).
DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = dateadd(mm, -1, getdate())
SET @StartDate = dateadd(dd, datepart(dd, getdate())*-1, @StartDate)
SET @EndDate = dateadd(mm, 1, @StartDate)
SELECT *
FROM Member
WHERE date_created BETWEEN @StartDate AND @EndDate
DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = DATEADD(mm, DATEDIFF(mm,0,getdate())-1, 0)
SET @EndDate = DATEADD(mm, 1, @StartDate)
SELECT *
FROM Member
WHERE date_created BETWEEN @StartDate AND @EndDate
mrdenny의 솔루션으로 업그레이드하면 지난달 YYYY-MM-01에서 정확히 얻을 수 있습니다.
지난 달은 그 달의 마지막 날까지로 간주합니다. 여기서 2016 년 1 월 31 일은 지난 30 일과 유사하지 않은 1 월 31 일이됩니다.
SELECT CONVERT(DATE, DATEADD(DAY,-DAY(GETDATE()),GETDATE()))
이를 수행하는 한 가지 방법은 DATEPART 함수를 사용하는 것입니다 .
select field1, field2, fieldN from TABLE where DATEPART(month, date_created) = 4
and DATEPART(year, date_created) = 2009
4 월의 모든 날짜를 반환합니다. 지난 달 (즉, 이번 달 이전)의 경우 GETDATE 및 DATEADD 도 사용할 수 있습니다 .
select field1, field2, fieldN from TABLE where DATEPART(month, date_created)
= (DATEPART(month, GETDATE()) - 1) and
DATEPART(year, date_created) = DATEPART(year, DATEADD(m, -1, GETDATE()))
declare @PrevMonth as nvarchar(256)
SELECT @PrevMonth = DateName( month,DATEADD(mm, DATEDIFF(mm, 0, getdate()) - 1, 0)) +
'-' + substring(DateName( Year, getDate() ) ,3,4)
select * from [member] where DatePart("m", date_created) = DatePart("m", DateAdd("m", -1, getdate())) AND DatePart("yyyy", date_created) = DatePart("yyyy", DateAdd("m", -1, getdate()))
DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = DATEADD(mm, DATEDIFF(mm, 0, getdate()) - 1, 0)
SET @EndDate = dateadd(dd, -1, DATEADD(mm, 1, @StartDate))
SELECT * FROM Member WHERE date_created BETWEEN @StartDate AND @EndDate
그리고 mrdenny의 솔루션에 대한 또 다른 업그레이드.
이전 달의 정확한 마지막 날도 제공합니다.
WHERE
date_created >= DATEADD(MONTH, DATEDIFF(MONTH, 31, CURRENT_TIMESTAMP), 0)
AND date_created < DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP), 0)
저는 Oracle 환경에서 왔으며 Oracle에서 다음과 같이 할 것입니다.
select * from table
where trunc(somedatefield, 'MONTH') =
trunc(sysdate -INTERVAL '0-1' YEAR TO MONTH, 'MONTH')
Idea: I'm running a scheduled report of previous month (from day 1 to the last day of the month, not windowed). This could be index unfriendly, but Oracle has fast date handling anyways. Is there a similar simple and short way in MS SQL? The answer comparing year and month separately seems silly to Oracle folks.
SQL query to get record of the present month only
SELECT * FROM CUSTOMER
WHERE MONTH(DATE) = MONTH(CURRENT_TIMESTAMP) AND YEAR(DATE) = YEAR(CURRENT_TIMESTAMP);
You can get the last month records with this query
SELECT * FROM dbo.member d
WHERE CONVERT(DATE, date_created,101)>=CONVERT(DATE,DATEADD(m, datediff(m, 0, current_timestamp)-1, 0))
and CONVERT(DATE, date_created,101) < CONVERT(DATE, DATEADD(m, datediff(m, 0, current_timestamp)-1, 0),101)
In Sql server for last one month:
select * from tablename
where order_date > DateAdd(WEEK, -1, GETDATE()+1) and order_date<=GETDATE()
DECLARE @curDate INT = datepart( Month,GETDATE())
IF (@curDate = 1)
BEGIN
select * from Featured_Deal
where datepart( Month,Created_Date)=12 AND datepart(Year,Created_Date) = (datepart(Year,GETDATE())-1)
END
ELSE
BEGIN
select * from Featured_Deal
where datepart( Month,Created_Date)=(datepart( Month,GETDATE())-1) AND datepart(Year,Created_Date) = datepart(Year,GETDATE())
END
DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = dateadd(mm, -1, getdate())
SET @StartDate = dateadd(dd, datepart(dd, getdate())*-1, @StartDate)
SET @EndDate = dateadd(mm, 1, @StartDate)
set @StartDate = DATEADD(dd, 1 , @StartDate)
The way I fixed similar issue was by adding Month to my SELECT portion
Month DATEADD(day,Created_Date,'1971/12/31') As Month
and than I added WHERE statement
Month DATEADD(day,Created_Date,'1971/12/31') = month(getdate())-1
If you are looking for last month so try this,
SELECT
FROM #emp
WHERE DATEDIFF(MONTH,CREATEDDATE,GETDATE()) = 1
If you are looking for last month so try this,
SELECT
FROM #emp
WHERE DATEDIFF(day,CREATEDDATE,GETDATE()) between 1 and 30
A simple query which works for me is:
select * from table where DATEADD(month, 1,DATEFIELD) >= getdate()
If you are looking for previous month data:
date(date_created)>=date_sub(date_format(curdate(),"%Y-%m-01"),interval 1 month) and
date(date_created)<=date_sub(date_format(curdate(),'%Y-%m-01'),interval 1 day)
This will also work when the year changes. It will also work on MySQL.
참고URL : https://stackoverflow.com/questions/1424999/get-the-records-of-last-month-in-sql-server
'programing tip' 카테고리의 다른 글
플랫리스트를 다시 렌더링하는 방법은 무엇입니까? (0) | 2020.11.16 |
---|---|
문자열에서 숫자 0-9 만 반환 (0) | 2020.11.16 |
javascript / jquery로 선행 0 제거 / 자르기 (0) | 2020.11.16 |
현장에서 중단 문제가 발생한 적이 언제입니까? (0) | 2020.11.16 |
AngularJS http get then Construct에서 오류 처리 (0) | 2020.11.16 |