programing tip

SQL 서버에서 지난달의 기록 가져 오기

itbloger 2020. 11. 16. 07:55
반응형

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. 검색중인 열의 색인을 무시합니다.
  2. 의지 (잠재적으로)는 의도하지 않은 데이터를 선택하여 결과를 자동으로 손상시킵니다.

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 월의 모든 날짜를 반환합니다. 지난 달 (즉, 이번 달 이전)의 경우 GETDATEDATEADD사용할 수 있습니다 .

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

반응형