Dans Microsoft SQL Server, j'ai un numéro de semaine
(from DATEPART(wk, datecol))
mais ce que je voudrais faire, c’est de remettre cela dans la période de cette semaine.
Par exemple,
SELECT DATEPART(wk, GETDATE())
rendements 10. Je voudrais tirer 3/1/2009 et 3/7/2009 de ce nombre.
Est-ce possible?
La réponse de Quassnoi fonctionne, mais vous laisse en quelque sorte sur le crochet pour nettoyer les dates si elles sont au milieu de la journée (son début de semaine vous laisse un jour plus tôt que vous n'auriez dû si vous utilisez un temps au milieu du jour - vous pouvez tester en utilisant GETDATE ()).
J'ai utilisé quelque chose comme ça dans le passé:
SELECT
CONVERT(varchar(50), (DATEADD(dd, @@DATEFIRST - DATEPART(dw, DATECOL), DATECOL)), 101),
CONVERT(varchar(50), (DATEADD(dd, @@DATEFIRST - DATEPART(dw, DATECOL) - 6, DATECOL)), 101)
Un des avantages de cela est qu’en utilisant @@ DATEFIRST, vous pouvez gérer les jours de début de semaine non standard (la valeur par défaut est dimanche, mais avec SET @@ DATEFIRST, vous pouvez le modifier).
Il semble fou que la simple manipulation de date dans SQL Server doive être aussi arcanique, mais voilà ...
Vous pouvez définir @WeekNum et @YearNum sur ce que vous voulez. Dans cet exemple, elles sont dérivées de la variable @datecol, qui est définie sur GETDATE () à des fins d'illustration. Une fois que vous avez ces valeurs, vous pouvez calculer la plage de dates pour une semaine en utilisant les éléments suivants:
DECLARE @datecol datetime = GETDATE (); DECLARE @WeekNum INT , @YearNum char (4); SELECT @WeekNum = DATEPART (WK, @datecol) , @YearNum = CAST (DATEPART (YY, @datecol) AS CHAR (4)); -- une fois que vous avez défini les paramètres @WeekNum et @YearNum, voici ce qui calcule la plage de dates . SELECT DATEADD (semaine, DATEDIFF (semaine, 6, '1/1 /' + @YearNum) + (@ WeekNum-1), 6) AS StartOfWeek; SÉLECTIONNER DATEADD (semaine, DATEDIFF (semaine, 5, '1/1/'+ @YearNum) + (@ WeekNum-1), 5) AS EndOfWeek;
Pour répondre à ta question:
--CHANGE A WEEK NUMBER BACK INTO A DATE FOR THE FIRST DATE OF THE WEEK
DECLARE @TaskWeek INT = 17
DECLARE @TaskYear INT = 2013
SELECT DATEADD(WEEK, @TaskWeek - 1,DATEADD(dd, 1 - DATEPART(dw, '1/1/' + CONVERT(VARCHAR(4),@TaskYear)), '1/1/' + CONVERT(VARCHAR(4),@TaskYear)))
Si votre semaine commence à partir de lundi (sur SQL Server 2008)
select datecol,
DATEPART(ISOWK, datecol) as week,
((DATEPART(dw, datecol)+5)%7)+1 as weekday,
(DATEADD(dd, -((DATEPART(dw, datecol)+5)%7), datecol)) as Monday,
(DATEADD(dd, -((DATEPART(dw, datecol)+5)%7)+6, datecol)) as Sunday
SELECT DATECOL - DATEPART(weekday, DATECOL), DATECOL - DATEPART(weekday, DATECOL) + 7
Que diriez-vous d’une fonction qui saute à la semaine qui précède le numéro de la semaine puis parcourt les prochains jours jusqu’à ce que le numéro de la semaine change (7 étapes au maximum) et renvoie la nouvelle date?
CREATE FUNCTION dbo.fnGetDateFromWeekNo
(@weekNo int , @yearNo int)
RETURNS smalldatetime
AS
BEGIN
DECLARE @tmpDate smalldatetime
set @tmpdate= cast(cast (@yearNo as varchar) + '-01-01' as smalldatetime)
-- jump forward x-1 weeks to save counting through the whole year
set @tmpdate=dateadd(wk,@weekno-1,@tmpdate)
-- make sure weekno is not out of range
if @WeekNo <= datepart(wk,cast(cast (@yearNo as varchar) + '-12-31' as smalldatetime))
BEGIN
WHILE (datepart(wk,@tmpdate)<@WeekNo)
BEGIN
set @tmpdate=dateadd(dd,1,@tmpdate)
END
END
ELSE
BEGIN
-- invalid weeknumber given
set @tmpdate=null
END
RETURN @tmpDate
END
J'ai pris la solution d'elindeblom et je l'ai modifiée - l'utilisation de chaînes (même si elles sont converties en dates) me rend nerveuse pour les différents formats de dates utilisés dans le monde. Cela évite ce problème.
Bien que non demandé, j'ai également inclus l'heure afin que la semaine se termine 1 seconde avant minuit:
DECLARE @WeekNum INT = 12,
@YearNum INT = 2014 ;
SELECT DATEADD(wk,
DATEDIFF(wk, 6,
CAST(RTRIM(@YearNum * 10000 + 1 * 100 + 1) AS DATETIME))
+ ( @WeekNum - 1 ), 6) AS [start_of_week],
DATEADD(second, -1,
DATEADD(day,
DATEDIFF(day, 0,
DATEADD(wk,
DATEDIFF(wk, 5,
CAST(RTRIM(@YearNum * 10000
+ 1 * 100 + 1) AS DATETIME))
+ ( @WeekNum + -1 ), 5)) + 1, 0)) AS [end_of_week] ;
Oui, je sais que je lance toujours mais à partir d'un nombre. C'est "plus sûr" pour moi.
Cela se traduit par:
start_of_week end_of_week
----------------------- -----------------------
2014-03-16 00:00:00.000 2014-03-22 23:59:59.000
Cela devrait fonctionner indépendamment de @@DATEFIRST
ALTER FUNCTION dbo.DEV_VW_WeekSerial
(@YearNum int,
@WeekNum int,
@DayNum int)
RETURNS Date AS
BEGIN
DECLARE @FirstDayYear As Date;
SET @FirstDayYear='01/01/' + CAST(@YearNum As varchar)
RETURN dateadd(d,(@DayNum-datepart(weekday,@FirstDayYear)),dateadd(week, @WeekNum-1,@FirstDayYear))
END
Donnez-lui @Year et @Week, Renvoyez la première date de cette semaine.
Declare @Year int
,@Week int
,@YearText varchar(4)
set @Year = 2009
set @Week = 10
set @YearText = @Year
print dateadd(day
,1 - datepart(dw, @YearText + '-01-01')
+ (@Week-1) * 7
,@YearText + '-01-01')
Je viens d'incorporer le SELECT à une instruction CASE (pour ma situation lundi marquait le premier jour de la semaine et ne voulait pas traiter de la commande SET DATEFIRST:
CASE DATEPART(dw,<YourDateTimeField>)
WHEN 1 THEN CONVERT(char(10), DATEADD(DD, -6, <YourDateTimeField>),126) + ' to ' + CONVERT(char(10), <YourDateTimeField>,126)
WHEN 2 THEN CONVERT(char(10), <YourDateTimeField>,126) + ' to ' + CONVERT(char(10), DATEADD(DD, 6, <YourDateTimeField>),126)
WHEN 3 THEN CONVERT(char(10), DATEADD(DD, -1, <YourDateTimeField>),126) + ' to ' + CONVERT(char(10), DATEADD(DD, 5, <YourDateTimeField>),126)
WHEN 4 THEN CONVERT(char(10), DATEADD(DD, -2, <YourDateTimeField>),126) + ' to ' + CONVERT(char(10), DATEADD(DD, 4, <YourDateTimeField>),126)
WHEN 5 THEN CONVERT(char(10), DATEADD(DD, -3, <YourDateTimeField>),126) + ' to ' + CONVERT(char(10), DATEADD(DD, 3, <YourDateTimeField>),126)
WHEN 6 THEN CONVERT(char(10), DATEADD(DD, -4, <YourDateTimeField>),126) + ' to ' + CONVERT(char(10), DATEADD(DD, 2, <YourDateTimeField>),126)
WHEN 7 THEN CONVERT(char(10), DATEADD(DD, -5, <YourDateTimeField>),126) + ' to ' + CONVERT(char(10), DATEADD(DD, 1, <YourDateTimeField>),126)
ELSE 'UNK'
END AS Week_Range
dateadd(
dd,
datepart(wk, @Date)*7,
convert(smalldatetime, convert(char,year(max(@Date)))+convert(char, '-01-01'))
)-1
La plupart des votes répondent, sauf la 1re semaine et la semaine dernière de l'année. Lorsque datecol est défini sur '2009-01-01' , le résultat est 01/03/2009 et 12/28/2008 .
Ma solution:
DECLARE @Date date = '2009-03-01', @WeekNum int, @StartDate date;
SELECT @WeekNum = DATEPART(WEEK, @Date);
SELECT @StartDate = DATEADD(DAY, -(DATEPART(WEEKDAY, DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date), 0)) + 6), DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date), 0));
SELECT CONVERT(nvarchar, CASE WHEN @WeekNum = 1 THEN CAST(DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date), 0) AS date) ELSE DATEADD(DAY, 7 * @WeekNum, @StartDate) END, 101) AS StartOfWeek
,CONVERT(nvarchar, CASE WHEN @WeekNum = DATEPART(WEEK, DATEADD(DAY, -1, DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date) + 1, 0))) THEN DATEADD(DAY, -1, DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date) + 1, 0)) ELSE DATEADD(DAY, 7 * @WeekNum + 6, @StartDate) END, 101) AS EndOfWeek;
Ceci affichera 01/01/2009 et 01/03/2009 pour la 1ère semaine, et affichera 03/01/2009 et 03/07/2009 pour le 10ème semaine.
Je pense que ce serait ce que vous voulez exactement. Vous pouvez remplacer les variables par leurs expressions à votre guise.
Ici, il vous suffit de passer l'année et le numéro de semaine.
DECLARE @Year VARCHAR(4)
SET @Year= '2012'
DECLARE @FirstDate DATETIME
SET @FirstDate = (SELECT DATEADD(dd,1,(SELECT DATEADD(wk,DATEPART(wk,GETDATE())-1,Convert(DAteTime,'01-01-' + @Year))))
)
DECLARE @LastDate DATETIME
SET @LastDate =(SELECT DATEADD(dd,4,@FirstDate))
SELECT @FirstDate
,@LastDate
DECLARE @dayval int,
@monthval int,
@yearval int
SET @dayval = 1
SET @monthval = 1
SET @yearval = 2011
DECLARE @dtDateSerial datetime
SET @dtDateSerial = DATEADD(day, @dayval-1,
DATEADD(month, @monthval-1,
DATEADD(year, @yearval-1900, 0)
)
)
DECLARE @weekno int
SET @weekno = 53
DECLARE @weekstart datetime
SET @weekstart = dateadd(day, 7 * (@weekno -1) - datepart (dw, @dtDateSerial), @dtDateSerial)
DECLARE @weekend datetime
SET @weekend = dateadd(day, 6, @weekstart)
SELECT @weekstart, @weekend
Cela fonctionne pour moi:
select
convert(varchar(50), dateadd(dd, - datepart(dw, DATECOL) + 1, DATECOL), 101),
convert(varchar(50), dateadd(dd, - datepart(dw, DATECOL) + 7, DATECOL), 101)
déclarer @IntWeek en tant que varchar (20) SET @IntWeek = '201820'
SELECT DATEADD (semaine, date de date (semaine, @@ DATEFIRST, GAUCHE (@ IntWeek, 4) + '- 01-01')) + (cast ((DROITE (@ IntWeek, 2) en tant que int) -1), @@ DATEFIRST) StartOfWeek
Je n'ai pas pris le temps de tester toutes les réponses, mais rien ne semble aussi simple et efficace:
DECLARE @WeekNum int
DECLARE @YearNum char(4)
SELECT DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + @YearNum) + (@WeekNum-1), 6) AS StartOfWeek
SELECT DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + @YearNum) + (@WeekNum-1), 5) AS EndOfWeek
SELECT DATEADD(week, @weekNumber - 1, DATEADD(DAY, @@datefirst - DATEPART(weekday, CAST(YEAR(GETDATE()) AS VARCHAR) + '-01-01') - 6, CAST(YEAR(GETDATE()) AS VARCHAR) + '-01-01'))
Réponse:
select DateAdd(day,-DATEPart(DW,<Date>), <Date>) [FirstDayOfWeek] ,DateAdd(day,-DATEPart(DW,<Date>)+6, <Date>) [LastDayOfWeek]
FROM <TABLE>