Hoe kan ek 'n dag van die jaar en 'emmer dit in weke van die jaar in Microsoft SQL? Gebruik in die vervaardiging van scenario's vir wesenlike vereistes

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

  •  03-07-2019
  •  | 
  •  

Vra

Ek het 'n behoefte aan 'n bruto vereistes verslag dat hoeveel vraag en aanbod van 'n item in voorraad en verder neem van 'n begin datum en 'emmers' dit in verskillende weke van die jaar te skep sodat materiaal beplanners weet wanneer hulle nodig sal hê 'n item en as hulle genoeg voorraad in voorraad op daardie tydstip.

As 'n voorbeeld, vandag se datum (verslag datum) is 8/27/08. Die eerste stap is om die datum vir die Maandag van die week die verslag datum val in vind. In hierdie geval, sal Maandag 8/25/08 wees. Dit word die eerste dag van die eerste emmer. Alle transaksies wat voor daardie val is aan week # 0 en sal saamgevat word as die begin balans vir die verslag. Die oorblywende emmers word bereken vanaf daardie punt. Vir die agtste emmer, is daar geen einde datum so enige transaksies daarna 8 emmer begin datum word beskou week # 8.

WEEK # begin einde
0 ....... Geen .......... 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 ...... Geen

Hoe kry ek die week #, begin datum, einddatum vir 'n gegewe datum?

Was dit nuttig?

Oplossing

Jy kan kry Maandag vir 'n gegewe datum in 'n week as:

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

en jy kan 'n gestoor proses met die volgende liggaam skryf

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

Wanneer ek slaag

@date = '20080827'

teen hierdie prosedure Ek kry die volgende

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

Ander wenke

Ek het nog altyd gevind dat dit die maklikste en mees doeltreffende (vir SQL Server) om 'n tafel te bou met 'n ry vir elke week in die toekoms deur jou domein horison; en sluit om wat (met 'n "WAAR GETDATE ()> = MONDATE EN NIE BESTAAN (SELECT 1 van die tafel WAAR MONDATE

Enigiets wat jy probeer om te doen met UDF se sal baie minder doeltreffend wees en ek het iets uitgevind moeilik om te gebruik.

- SQL stel die eerste dag van die week as Sondag en vir ons doeleindes ons wil hê dit moet Maandag
. --This opdrag doen dit.

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

Die probleem wat ek sien met die een emmer op 'n slag benadering is dat dit is moeilik om dit skaal maak,

As jy aansluit by 'n gebruiker-gedefinieerde funksie wat jy sal beter prestasie kry, kan jy hierdie aa gebruik beginpunt

Hoekom nie 'n kombinasie van DATEPART (jaar, datum-kolom) en DATEPART (week, datum-kolom) en groep gebruik deur hierdie waardes. Dit werk as die week in DATEPART is in lyn op Maandae as ISO 8601 vereis. In uiteensetting:

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...
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top