1

我需要创建一个总需求报告,从开始日期开始计算库存中物品的供应和需求量,并将其“存储”到一年中的不同周,以便物料计划人员知道他们何时需要物品和如果他们当时有足够的库存。

例如,今天的日期(报告日期)是 8/27/08。第一步是找到报告日期所在周的星期一的日期。在这种情况下,星期一将是 8/25/08。这成为第一个桶的第一天。在此之前的所有交易都分配到第 0 周,并将汇总为报表的期初余额。剩余的桶是从那个点开始计算的。对于第 8 个存储桶,没有结束日期,因此在第 8 个存储桶开始日期之后的任何交易都被视为第 8 周。

WEEK# 开始日期 结束日期
0.......无............8/24/08
1.......8/25/08...... 2008年 8 月 31
日 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
......无

如何获取给定日期的周#、开始日期、结束日期?

4

5 回答 5

2

我一直发现(对于 SQL Server)最简单和最有效的方法是在您的域范围内为未来每周构建一个包含一行的表;并加入其中(使用“WHERE GETDATE() >= MONDATE AND NOT EXISTS (SELECT 1 FROM table WHERE MONDATE < GETDATE())”。

你尝试用 UDF 做的任何事情都会效率低得多,而且我发现更难使用。

于 2009-01-07T06:25:29.413 回答
1

您可以在一周内的任何给定日期获得星期一:

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
于 2009-01-07T08:20:57.807 回答
0

--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
于 2009-01-07T06:16:04.923 回答
0

我在一次一个桶的方法中看到的问题是它很难扩展,

如果您加入用户定义的函数,您将获得更好的性能,您可以以此为起点

于 2009-01-07T06:22:19.357 回答
0

为什么不使用 DATEPART(year, date-column) 和 DATEPART(week, date-column) 的组合并按这些值分组。如果DATEPART中的星期按照 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...
于 2009-01-07T08:48:47.407 回答