كيف يمكنني اتخاذ يوم من أيام السنة و'دلو انه في الأسابيع من السنة في Microsoft SQL؟ المستخدمة في التصنيع سيناريوهات لتلبية الاحتياجات المادية

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

  •  03-07-2019
  •  | 
  •  

سؤال

ولدي حاجة لإنشاء تقرير احتياجات الإجمالي الذي يأخذ كم العرض والطلب على بند في المخزون من تاريخ بدء فصاعدا و "دلاء" أنه في الأسابيع مختلفة من السنة بحيث يعرف المخططين المادي عندما ستحتاج عنصر وإذا كان لديهم مخزون كاف في المخزون في ذلك الوقت.

وعلى سبيل المثال، تاريخ اليوم (تاريخ التقرير) هو 8/27/08. الخطوة الأولى هي العثور على موعد يوم الاثنين من الاسبوع تاريخ التقرير يقع في. في هذه الحالة، سوف يكون الاثنين 8/25/08. هذا يصبح في اليوم الأول من المجموعة الأولى. يتم تعيين كافة المعاملات التي تقع قبل ذلك لمدة أسبوع و# 0 وسيتم تلخيصها الرصيد بداية التقرير. وتحسب الدلاء المتبقية من تلك النقطة. لدلو الثامن، لا يوجد تاريخ انتهاء لذلك تعتبر أي معاملات بعد ذلك التاريخ دلو بداية 8TH الأسبوع رقم 8.

وWEEK # تاريخ البدء تاريخ الانتهاء
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 AND NOT EXISTS (SELECT 1 من الجدول حيث MONDATE

وأي شيء تحاول أن تفعل مع لUDF سيكون أقل كفاءة بكثير، وأجد أكثر صعوبة للاستخدام.

و- SQL يحدد اليوم الأول من الأسبوع، الأحد ولأغراضنا نحن نريد أن يكون الاثنين
. قيادة --This يفعل ذلك.

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

والمشكلة أرى مع دلو واحد على نهج الوقت هو أن من الصعب أن تجعل من الحجم،

إذا كنت الانضمام الى وظيفة المعرفة ستحصل على أداء أفضل، يمكنك استخدام هذا أأ نقطة انطلاق

لماذا لا تستخدم مزيجا من 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...
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top