Microsoft SQL에서 일년 중 하루를 어떻게하고 일년 중 몇 주 동안 '버킷'을해야합니까? 재료 요구 사항에 대한 제조 시나리오에 사용됩니다

StackOverflow https://stackoverflow.com/questions/419372

  •  03-07-2019
  •  | 
  •  

문제

시작 날짜부터 재고에서 품목의 공급과 수요가 얼마나 많은지를 가져 와서 재료 플래너가 항목이 필요한시기를 알 수 있도록 일년 중 다른 주로 '버킷'을 '버킷'하는 총 요구 사항 보고서를 작성해야합니다. 그 당시 재고에 충분한 주식이있는 경우.

예를 들어, 오늘 날짜 (보고서 날짜)는 8/27/08입니다. 첫 번째 단계는 보고서 날짜가 시작되는 주 월요일의 날짜를 찾는 것입니다.이 경우 월요일은 8/25/08입니다. 이것은 첫 번째 버킷의 첫날이됩니다. 그 이전의 모든 거래는 0 주에 할당되며 보고서의 시작 잔액으로 요약됩니다. 나머지 버킷은 그 시점에서 계산됩니다. 여덟 번째 버킷의 경우 종료 날짜가 없으므로 8 번째 버킷 시작 날짜 이후의 거래는 8 주차로 간주됩니다.

주# 시작 날짜 종료 날짜
0 ....... 없음 .......... 8/24/08
1.......8/25/08.......8/31/08
2.......9/1/08.........9/7/08
3.......9/8/08.........9/14/08
4.......9/15/08.......9/21/08
5.......9/22/08.......9/28/08
6.......9/29/08.......10/5/08
7.......10/06/08.....10/12/08
8 ....... 10/13/08 ...... 없음

주어진 날짜, 시작 날짜, 주어진 날짜의 주중을받는 방법은 무엇입니까?

도움이 되었습니까?

해결책

일주일에 주어진 날짜에 대해 월요일에 다음과 같이받을 수 있습니다.

DATEADD(d, 1 - DATEPART(dw, @date), @date)

다음 몸체로 저장된 절차를 쓸 수 있습니다.

-- find Monday at that week
DECLARE @currentDate SMALLDATETIME
SELECT @currentDate = DATEADD(d, 1 - DATEPART(dw, @date), @date)

-- create a table and insert the first record
DECLARE @weekTable TABLE (Id INT, StartDate SMALLDATETIME, EndDate SMALLDATETIME)
INSERT INTO @weekTable VALUES (0, NULL, @currentDate)

-- increment the date
SELECT @currentDate = DATEADD(d, 1, @currentDate)

-- iterate for 7 more weeks
DECLARE @id INT
SET @id = 1
WHILE @id < 8
BEGIN
    INSERT INTO @weekTable VALUES (@id, @currentDate, DATEADD(d, 6, @currentDate))
    SELECT @currentDate = DATEADD(ww, 1, @currentDate)
    SET @id = @id + 1
END

-- add the last record
INSERT INTO @weekTable VALUES (8, @currentDate, NULL)

-- select the values
SELECT Id 'Week #', StartDate 'Start Date', EndDate 'End Date'
FROM @weekTable

내가 지나갈 때

@date = '20080827'

이 절차에서 나는 다음을 얻는다

Week #  Start Date     End Date
0   NULL                2008-08-24 00:00:00
1   2008-08-25 00:00:00 2008-08-31 00:00:00
2   2008-09-01 00:00:00 2008-09-07 00:00:00
3   2008-09-08 00:00:00 2008-09-14 00:00:00
4   2008-09-15 00:00:00 2008-09-21 00:00:00
5   2008-09-22 00:00:00 2008-09-28 00:00:00
6   2008-09-29 00:00:00 2008-10-05 00:00:00
7   2008-10-06 00:00:00 2008-10-12 00:00:00
8   2008-10-13 00:00:00 NULL

다른 팁

나는 항상 도메인 지평을 통해 매주 하나의 행이있는 테이블을 구성하는 것이 가장 쉽고 효율적인 (SQL Server의 경우)를 발견했습니다. 그에 가입하십시오 ( "getDate ()> = mondate가 존재하지 않고 존재하지 않습니다 (mondate <getDate ())가있는 테이블에서 1을 선택하십시오."

UDF로 시도하는 것은 훨씬 덜 효율적이며 사용하기가 더 어렵습니다.

-SQL은 주일의 첫날을 일요일로 설정하고 목적을 위해 월요일이되기를 원합니다.
-이 명령은 그렇게합니다.

SET DATEFIRST 1

DECLARE 
    @ReportDate DATETIME, 

    @Weekday INTEGER, 
    @NumDaysToMonday INTEGER, 
    @MondayStartPoint DATETIME,
    @MondayStartPointWeek INTEGER,
    @DateToProcess DATETIME,
    @DateToProcessWeek INTEGER,
    @Bucket VARCHAR(50),
    @DaysDifference INTEGER,
    @BucketNumber INTEGER,
    @NumDaysToMondayOfDateToProcess INTEGER,
    @WeekdayOfDateToProcess INTEGER,
    @MondayOfDateToProcess DATETIME,
    @SundayOfDateToProcess DATETIME

SET @ReportDate = '2009-01-01'
print @ReportDate

SET @DateToProcess = '2009-01-26'
--print @DateToProcess

SET @Weekday = (select DATEPART ( dw , @ReportDate ))
--print @Weekday

--print DATENAME(dw, @ReportDate)

SET @NumDaysToMonday = 
    (SELECT
      CASE 
         WHEN @Weekday =  1 THEN 0
         WHEN @Weekday =  2 THEN 1
         WHEN @Weekday =  3 THEN 2
         WHEN @Weekday =  4 THEN 3
         WHEN @Weekday =  5 THEN 4
         WHEN @Weekday =  6 THEN 5
         WHEN @Weekday =  7 THEN 6
      END)

--print @NumDaysToMonday

SET @MondayStartPoint =  (SELECT DATEADD (d , -1*@NumDaysToMonday, @ReportDate))
--print @MondayStartPoint

SET @DaysDifference = DATEDIFF ( dd , @MondayStartPoint , @DateToProcess )
--PRINT @DaysDifference

SET @BucketNumber = @DaysDifference/7
--print @BucketNumber

----Calculate the start and end dates of this bucket------
PRINT 'Start Of New Calc'

print @DateToProcess

SET @WeekdayOfDateToProcess = (select DATEPART ( dw , @DateToProcess ))
print @WeekdayOfDateToProcess

SET @NumDaysToMondayOfDateToProcess= 
    (SELECT
      CASE 
         WHEN @WeekdayOfDateToProcess =  1 THEN 0
         WHEN @WeekdayOfDateToProcess =  2 THEN 1
         WHEN @WeekdayOfDateToProcess =  3 THEN 2
         WHEN @WeekdayOfDateToProcess =  4 THEN 3
         WHEN @WeekdayOfDateToProcess =  5 THEN 4
         WHEN @WeekdayOfDateToProcess =  6 THEN 5
         WHEN @WeekdayOfDateToProcess =  7 THEN 6
      END)

print @NumDaysToMondayOfDateToProcess
SET @MondayOfDateToProcess =  (SELECT DATEADD (d , -1*@NumDaysToMondayOfDateToProcess, @DateToProcess))
print @MondayOfDateToProcess   ---This is the start week

SET @SundayOfDateToProcess = (SELECT DATEADD (d , 6, @MondayOfDateToProcess))
PRINT @SundayOfDateToProcess

한 번에 한 번의 버킷에서 볼 수있는 문제는 규모를 확장하기가 어렵다는 것입니다.

사용자 정의 된 기능에 가입하면 더 나은 성능을 얻을 수 있습니다. 이 AA 시작점

DatePart (Year, Date-Column) 및 DatePart (주, Date-Column) 와이 값별로 그룹을 사용해보십시오. 이번 주에 작동합니다 날짜 부분 ISO 8601이 요구하는대로 월요일에 정렬됩니다. 개요 :

SELECT DATEPART(year, date_column) AS yyyy,
       DATEPART(week, date_column) AS ww,
       ...other material as required...
    FROM SomeTableOrOther
    WHERE ...appropriate filters...
    GROUP BY yyyy, ww -- ...and other columns as necessary...
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top