我需要创建一个总需求报告,该报告从开始日期开始计算库存中物品的供应和需求量,并将其“桶”分配到一年中的不同周,以便物料计划员知道何时需要一个项目,如果他们当时有足够的库存库存。
例如,今天的日期(报告日期)是8/27/08。第一步是找到报告日期所在星期一的日期。在这种情况下,星期一将是8/25/08。这成为第一桶的第一天。之前的所有交易都将分配到第0周,并将汇总为报告的期初余额。剩下的桶是从那一点计算出来的。对于第八个存储桶,没有结束日期,因此在第8个存储桶开始日期之后的任何事务都被视为第8周。
周#开始日期结束日期
0 .......无.......... 08年8月24日
1 ....... 08年8月25日08年8月31日.......
2 ....... 08年9月1日08年9月7日.........
3 ....... 08年9月8日08年9月14日.........
4 ....... 08年9月15日08年9月21日.......
5 ....... 08年9月22日08年9月28日.......
6 ....... 9/29/08 ....... 08年10月5日
7 ....... 10/06/08 .....零八年十月一十二日
8 ....... 08年10月13日......无
如何获得给定日期的周#,开始日期,结束日期?
答案 0 :(得分:2)
我总是发现最容易和最有效的(对于SQL Server)通过域范围构建一个每周一行的表格;并加入到那里(使用“WHERE GETDATE()> = MONDATE AND NOT EXISTS(SELECT 1 FROM table WHERE MONDATE< GETDATE())”。
你试图用UDF做的任何事情效率都会低得多,而且我发现它更难以使用。
答案 1 :(得分: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
答案 2 :(得分: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
答案 3 :(得分:0)
我一次看到一个桶的问题是难以扩展,
如果您加入用户定义的功能,您将获得更好的性能,您可以使用this a a starting point
答案 4 :(得分:0)
为什么不使用DATEPART(年,日期 - 列)和DATEPART(周,日期 - 列)的组合并按这些值分组。如果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...