2012-09-19 709 views
5

Lo intenté pero no pude obtener la solución correcta. Quiero una consulta SQL que enumere todas las fechas de fin de semana del año actual.¿Cómo obtener todas las fechas de fin de semana del año actual en SQL?

yo probamos este consulta SQL:

WITH hier(num, lvl) AS (
    SELECT 0, 1 
      UNION ALL 
    SELECT 100, 1 
      UNION ALL 
    SELECT num + 1, lvl + 1 
    FROM hier 
    WHERE lvl < 100 
) 
SELECT lvl [Week], 
convert(date,DATEADD(dw, -DATEPART(dw, DATEADD(wk,DATEDIFF(wk,0,'12/31/'+convert(nvarchar,YEAR(getdate()))), 0)+6), 
DATEADD(wk, DATEDIFF(wk,0,'12/31/'+convert(nvarchar,YEAR(getdate()))), 0)+6) - num * 7,101) [End Date] 
FROM hier a 
where num < 52 
ORDER BY [End Date] asc 

Su salida es la siguiente:

Week End date 
52 2012-01-14 
51 2012-01-21 
50 2012-01-28 
49 2012-02-04 

Quiero las fechas para empezar desde el principio - es así, lo anterior no se encuentra un fin de semana, lo cual es 2012-07-01. Además, quiero que los números de la semana aparezcan como 1, 2, 3... en lugar de 52, 51....

+0

En primer lugar, definen lo que * * decir con la fecha de fin de semana - diferentes culturas definen estas cosas de manera diferente. Suponiendo que se refiera a un fin de semana como los sábados y domingos, ¿qué fecha necesita? El sábado, el domingo, ¿ambos? Si ambos, como dos columnas en una sola fila, o como filas separadas? –

+0

fecha de finalización es el sábado –

Respuesta

5

Salida posterior this blog.

Su pregunta se explica en detalle.

DECLARE @Year AS INT, 
@FirstDateOfYear DATETIME, 
@LastDateOfYear DATETIME 
-- You can change @year to any year you desire 
SELECT @year = 2010 
SELECT @FirstDateOfYear = DATEADD(yyyy, @Year - 1900, 0) 
SELECT @LastDateOfYear = DATEADD(yyyy, @Year - 1900 + 1, 0) 
-- Creating Query to Prepare Year Data 
;WITH cte AS (
SELECT 1 AS DayID, 
@FirstDateOfYear AS FromDate, 
DATENAME(dw, @FirstDateOfYear) AS Dayname 
UNION ALL 
SELECT cte.DayID + 1 AS DayID, 
DATEADD(d, 1 ,cte.FromDate), 
DATENAME(dw, DATEADD(d, 1 ,cte.FromDate)) AS Dayname 
FROM cte 
WHERE DATEADD(d,1,cte.FromDate) < @LastDateOfYear 
) 
SELECT FromDate AS Date, Dayname 
FROM CTE 
WHERE DayName LIKE 'Sunday' 
/* 
WHERE DayName IN ('Saturday,Sunday') -- For Weekend 
WHERE DayName NOT IN ('Saturday','Sunday') -- For Weekday 
WHERE DayName LIKE 'Monday' -- For Monday 
WHERE DayName LIKE 'Sunday' -- For Sunday 
*/ 
OPTION (MaxRecursion 370) 
+0

pero me puede decir cómo puedo una columna más que imprimir la semana 1, semana 2, etc ... –

+1

Esta solución se basa en que el usuario tenga la configuración de idioma Inglés (otras culturas tendrían diferentes nombres fecha) –

+2

@ Kartik Patel WeekofYr = DATEPART (SEMANA, FromDate) .Incluso mi consulta hace lo mismo –

0

Trata de encontrar el primer sábado al hacer esto:

  1. Inicio en 2012-01-01
  2. Si no es un sábado, añadir un día
  3. Goto 2

Luego, en una tabla temporal, agregue esa fecha y la siguiente (domingo). Después de eso, debe pasar el siguiente:

  1. Añadir 7 y 8 días para el último sábado que has encontrado (se obtiene el siguiente sábado y domingo)
  2. Compruebe si están todavía en 2012
  3. Si están , guárdelos en la tabla temporal y vaya a 1

Puede haber formas más elegantes, pero esa es mi rápida solución & sucia. Como no ha publicado ningún código de lo que ha intentado, le dejaré la implementación a usted.

0

puede probar esta

DECLARE @FirstDateOfYear DATETIME 
SET @FirstDateOfYear = ’2010-01-01′ 
SELECT DISTINCT DATEADD(d, number, @FirstDateOfYear), 
CASE DATEPART(dw, DATEADD(d, number, @FirstDateOfYear)) 
WHEN 7 THEN ‘Saturday’ 
WHEN 1 THEN ‘Sunday’ 
ELSE ‘Work Day’ 
END 
FROM master..spt_values 
WHERE number BETWEEN 0 AND 364 
AND (DATEPART(dw, DATEADD(d, number, @FirstDateOfYear)) = 1 OR DATEPART(dw, DATEADD(d, number, @FirstDateOfYear)) = 7) 
ORDER BY DATEADD(d, number, @FirstDateOfYear) 
3

ayudará esto a

DECLARE @startDate DATETIME, @endDate DATETIME 
SELECT @startDate = '2012-01-01', @endDate = '2012-12-31' 
;WITH Calender AS (
    SELECT @startDate AS dt 
    UNION ALL 
    SELECT dt + 1 FROM Calender 
    WHERE dt + 1 <= @endDate 
) 
SELECT 
dt 
,NameMonth = DATENAME(Month, dt) 
,NameDay = DATENAME (Weekday,dt) 
,WeekofYr = DATEPART(WEEK, dt) FROM Calender 
WHERE DATENAME (Weekday,dt) IN ('Sunday') 
Option(MaxRecursion 0) 

resultado (parcial)

dt      NameMonth NameDay WeekofYr 
2012-01-01 00:00:00.000 January  Sunday 1 
2012-01-08 00:00:00.000 January  Sunday 2 
............................................... 
............................................... 
2012-12-30 00:00:00.000 December Sunday 53  
+0

Esta solución también * * se basa en que el usuario tenga la configuración de idioma Inglés (otras culturas tendrían diferentes nombres de fecha) –

0

Esto también funciona

declare @dat datetime, @add int 

set @dat = '20120101' 
set @add = datepart(w,@dat) 

set @add = 5 - @add -- friday 

set @dat = dateadd(d,@add,@dat) 

while @dat <= '20121231' 
begin 
    print @dat 
    set @dat = dateadd(d,7,@dat) 
end 
0
;with AllDaysOfYear (Day) as (
    select DATEADD(year,DATEDIFF(year,0,CURRENT_TIMESTAMP),0) --Jan 1st 
    union all 
    select DATEADD(day,1,Day) from AllDaysOfYear 
    where DATEPART(year,DATEADD(day,1,Day)) = DATEPART(year,CURRENT_TIMESTAMP) 
) 
select 
    ROW_NUMBER() OVER (ORDER BY Day) as WeekNo, 
    Day 
from 
    AllDaysOfYear 
where 
    DATEPART(weekday,Day) = DATEPART(weekday,'20120714') 
option (maxrecursion 0) 

En primer lugar, generar un conjunto de todos los días en el año en curso (AllDaysInYear). Luego, seleccione aquellos cuyo weekday es un sábado. El valor que he usado ('20120714') no es tan importante - sólo tiene que ser cualquier sábado, de cualquier año. Solo lo estoy usando para evitar tener que tener una configuración de idioma DATEFIRST particular.

0

Esta consulta muestra cómo obtener el primer día de este año y el primer día del año que viene en la primera parte. El primer día del próximo año se calcula una vez para no seguir recibiendo y comparando las partes del año.

;WITH cte(TheDate,NextYear) AS 
(
    SELECT CAST(CONVERT(CHAR(4),GETDATE(),112)+'0101' AS DATETIME), 
     CAST(YEAR(GETDATE())*10000+10101 AS CHAR(8)) 
    UNION ALL 
    SELECT DateAdd(d,1,TheDate),NextYear 
    FROM cte 
    WHERE DateAdd(d,1,TheDate)<NextYear 
) 
    SELECT Week = DatePart(wk,TheDate), 
     TheDate 
    FROM cte 
    WHERE DateName(dw,TheDate) in ('Saturday') 
ORDER BY TheDate 
OPTION (MAXRECURSION 366) 
0
with t as 
(
select 1 b 
union all 
select 1 b 
union all 
select 1 b 
union all 
select 1 b 
union all 
select 1 b 
union all 
select 1 b 
union all 
select 1 b 
union all 
select 1 b 
) 
select * from 
(
select 
current_timestamp 
-datepart(dy,current_timestamp) 
+row_number() over (order by t.b) d 
from t, t t1, t t2 
) tmp 
where datepart(yyyy,d)=datepart(yyyy,current_timestamp) 
     and 
     DATENAME(dw,d)='sunday' 
Cuestiones relacionadas