Wie nehme ich einen Tag des Jahres und bucket es in Wochen des Jahres in Microsoft SQL? Verwenden in den Fertigungsszenarien für den Materialbedarf

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

  •  03-07-2019
  •  | 
  •  

Frage

Ich habe eine Notwendigkeit, einen Bruttobedarf Bericht zu erstellen, wie viel Angebot und Nachfrage eines Artikel im Bestand ab von einem Startdatum dauert und ‚Eimer‘ in verschiedene Wochen des Jahres, so dass Disponenten wissen, wann sie brauchen ein Punkt, und wenn sie zu dieser Zeit im Lager genug Lager haben.

Als Beispiel der heutige Datum (Bericht Datum) ist 8/27/08. Der erste Schritt ist das Datum für den Montag der Woche des Bericht Datum fällt zu finden. In diesem Fall Montag 8/25/08 wäre. Dies wird der erste Tag des ersten Eimer. Alle Transaktionen, die vor, die fallen werden Woche # 0 zugeordnet und wird als Anfangssaldo für den Bericht zusammengefasst werden. Die restlichen Eimer werden von diesem Punkt berechnet. Zum achten Eimer gibt es kein Enddatum so dass alle Transaktionen nach dem 8.en Eimer Startdatum Woche # 8 berücksichtigt werden.

WOCHE # Beginn Ende
0 ....... Keine .......... 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 ...... Keine

Wie kann ich die Woche # bekommen, Startdatum, Enddatum für ein bestimmtes Datum?

War es hilfreich?

Lösung

Sie können Montag erhalten für einen bestimmten Zeitpunkt in einer Woche als:

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

und Sie können eine gespeicherte Prozedur mit dem folgenden Körper

schreiben
-- 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

Wenn ich pass

@date = '20080827'

zu diesem Verfahren, erhalte ich die folgende

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

Andere Tipps

Ich habe immer gefunden, ist es am einfachsten und effizientesten (für SQL Server) eine Tabelle mit einer Zeile für jede Woche in die Zukunft durch Ihren Domain-Horizont zu konstruieren; und kommen zu, dass (mit einem "WHERE GETDATE ()> = MONDATE UND NICHT VORHANDEN (SELECT 1 FROM Tabelle WHERE MONDATE

Alles, was Sie versuchen, mit UDF zu tun, wird viel weniger effizient, und ich finde schwieriger zu bedienen.

- SQL setzt den ersten Tag der Woche als Sonntag und für unsere Zwecke wollen wir es Montag sein
. --Dieser Befehl tut das.

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

Das Problem, das ich mit dem einem Eimer zu einem Zeitpunkt Ansatz zu sehen ist, dass sein schwer es Maßstab zu machen,

Wenn Sie in einer benutzerdefinierten Funktion beitreten werden Sie eine bessere Leistung erhalten, können Sie diese aa verwenden Ausgangspunkt

Warum nicht eine Kombination von DATEPART (Jahr, Datum-Spalte) und DATEPART (Woche, Datum-Spalte) und die Gruppe durch diese Werte verwenden. Dies funktioniert, wenn die Woche in DATEPART montags als ISO 8601 ausgerichtet ist, erfordert. Kurz umrissen:

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...
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top