de responder por qué usted está recibiendo un lunes y no un domingo:
Has añadido varias semanas a la fecha 0. ¿Qué es la fecha 0? 1900-01-01. ¿Cuál fue el día en 1900-01-01? Lunes. Entonces, en su código, ¿cuántas semanas han pasado desde el lunes 1 de enero de 1900? Llamemos a eso [n]. De acuerdo, ahora agregue [n] semanas al lunes, 1 de enero de 1900. No debería sorprenderse que esto termine siendo un lunes. DATEADD
no tiene idea de que quiere agregar semanas, pero solo hasta que llegue a un domingo, solo agregue 7 días, luego agregue 7 días más, ... al igual que DATEDIFF
, solo reconoce los límites que se han cruzado. Por ejemplo, éstos tanto volver 1, a pesar de que algunas personas se quejan de que no debe haber cierta lógica sensata incorporado para redondear hacia arriba o hacia abajo:
SELECT DATEDIFF(YEAR, '2010-01-01', '2011-12-31');
SELECT DATEDIFF(YEAR, '2010-12-31', '2011-01-01');
Para responder a cómo conseguir un Domingo:
Si quieres un domingo, luego elige una fecha base que no sea un lunes sino un domingo. Por ejemplo:
DECLARE @dt DATE = '1905-01-01';
SELECT [start_of_week] = DATEADD(WEEK, DATEDIFF(WEEK, @dt, CURRENT_TIMESTAMP), @dt);
Esto no se romperá si se cambia la configuración de DATEFIRST
(o su código se ejecuta para un usuario con una configuración diferente) - siempre y cuando usted todavía desea un domingo, independientemente del ajuste actual.Si quiere esas dos respuestas para jive, entonces debe usar una función que hace según la configuración DATEFIRST
, p.
SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP);
Así que si cambia la configuración de DATEFIRST
a lunes, martes, lo que tiene, el comportamiento cambiará. En función de la conducta que desea, se puede utilizar una de estas funciones:
CREATE FUNCTION dbo.StartOfWeek1 -- always a Sunday
(
@d DATE
)
RETURNS DATE
AS
BEGIN
RETURN (SELECT DATEADD(WEEK, DATEDIFF(WEEK, '19050101', @d), '19050101'));
END
GO
... o ...
CREATE FUNCTION dbo.StartOfWeek2 -- always the DATEFIRST weekday
(
@d DATE
)
RETURNS DATE
AS
BEGIN
RETURN (SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, @d), @d));
END
GO
Ahora, usted tiene un montón de alternativas, pero cuál funciona mejor? Me sorprendería si hubiera diferencias importantes, pero recolecté todas las respuestas proporcionadas hasta el momento y las realicé en dos series de pruebas, una barata y otra cara. Medí las estadísticas del cliente porque no veo que la E/S o la memoria desempeñen un papel en el rendimiento aquí (aunque pueden entrar en juego dependiendo de cómo se usa la función). En mis pruebas, los resultados son:
consulta cesión "barato":
Function - client processing time/wait time on server replies/total exec time
Gandarez - 330/2029/2359 - 0:23.6
me datefirst - 329/2123/2452 - 0:24.5
me Sunday - 357/2158/2515 - 0:25.2
trailmax - 364/2160/2524 - 0:25.2
Curt - 424/2202/2626 - 0:26.3
"caro" consulta asignación:
Function - client processing time/wait time on server replies/total exec time
Curt - 1003/134158/135054 - 2:15
Gandarez - 957/142919/143876 - 2:24
me Sunday - 932/166817/165885 - 2:47
me datefirst - 939/171698/172637 - 2:53
trailmax - 958/173174/174132 - 2:54
que pueden retransmitir los detalles de mis pruebas, si lo desea - parar aquí ya que esto ya se está volviendo bastante largo. Me sorprendió un poco ver que Curt aparecía como el más rápido en el extremo superior, dada la cantidad de cálculos y el código en línea. Tal vez haga algunas pruebas más exhaustivas y bloguee sobre ello ... si ustedes no tienen ninguna objeción al publicar sus funciones en otro lado.
'(@@ DATEFIRST + DATEPART (DW, @SomeDate))% 7' permanece constante independientemente de la configuración' @@ datefirst', creo. Con Monday = 2. –