2011-02-11 22 views

Respuesta

12

Esto lo hará:

select ((next_day(date2-7,'FRI')-next_day(date-1,'FRI'))/7)+1 as num_fridays 
from data 

Quizás lo mejor si rompo que re propio. La función NEXT_DAY devuelve el día siguiente que es (viernes en este caso) después de la fecha.

Así que para encontrar el primer viernes después de d1 sería:

next_day(d1, 'FRI') 

Pero si d1 es un viernes que devolvería el siguiente viernes, por lo que ajustar:

next_day(d1-1, 'FRI') 

mismo modo para encontrar la el último viernes hasta e incluyendo d2 hacemos:

next_day(d1-7, 'FRI') 

Restar el 2 da una cantidad de días : 0 si son la misma fecha, 7 si una re una semana de diferencia y así sucesivamente:

next_day(d1-7, 'FRI') - next_day(d1-1, 'FRI') 

Conversor de semana:

(next_day(d1-7, 'FRI') - next_day(d1-1, 'FRI'))/7 

Por último, si son la misma fecha en que recibimos 0 , pero en realidad hay 1 viernes, y así sucesivamente para que agregue:

((next_day(d1-7, 'FRI') - next_day(d1-1, 'FRI'))/7) + 1 
+4

+1, pero tenga en cuenta que la función next_day() depende de los parámetros de NLS y mejor utilizar la fecha del viernes conocida para obtener una cadena constante en lugar de la cadena 'FRI': to_char (to_date ('20110211', 'aaaammdd'), 'day') – ThinkJet

+0

¡Solución impresionante! Pude jugar y hacer mucho más con eso. ¡Muchas gracias! – mathielo

1
select sum(case when trim(to_char(to_date('2009-01-01','YYYY-MM-DD')+rownum,'Day')) = 'Friday' then 1 else 0 end) number_of_fridays 
from dual 
connect by level <= to_date('&end_date','YYYY-MM-DD') - to_date('&start_date','YYYY-MM-DD')+1; 

original fuente - http://forums.oracle.com/forums/thread.jspa?messageID=3987357&tstart=0

+0

Funciona bien, pero falla para 2011-02- 17 (fecha de finalización) y 2011-01-01 (fecha de inicio) ... – ssahu

0

intente modificar este:

CREATE OR REPLACE FUNCTION F_WORKINGS_DAYS 
(V_START_DATE IN DATE, V_END_DATE IN DATE) 

RETURN NUMBER IS 
DAY_COUNT NUMBER := 0; 
CURR_DATE DATE; 

BEGIN -- loop through and update 
CURR_DATE := V_START_DATE; 
WHILE CURR_DATE <= V_END_DATE 
LOOP 
    IF TO_CHAR(CURR_DATE,'DY') NOT IN ('SAT','SUN') -- Change this bit to ignore all but Fridays 
     THEN DAY_COUNT := DAY_COUNT + 1; 
    END IF; 
    CURR_DATE := CURR_DATE + 1; 
END LOOP; 

    RETURN DAY_COUNT; 
END F_WORKINGS_DAYS; 

/

2

Ver:

Why should I consider using an auxiliary calendar table?

El código del artículo es específicamente para SQL Server pero las técnicas son portátiles para la mayoría de las plataformas SQL.

Con una mesa de calendario en su lugar la consulta podría ser tan simple como

SELECT COUNT(*) AS friday_tally 
    FROM YourTable AS T1 
     INNER JOIN Calendar AS C1 
      ON C1.dt BETWEEN T1.start_date AND T1.end_date 
WHERE C1.day_name = 'Friday'; -- could be a numeric code 
+1

Prometo siempre subir la fecha de una tabla de calendario. Prometo siempre subir la fecha de una tabla de calendario. Prometo siempre subir la fecha de una tabla de calendario. –

6

tengo que tirar mi granito de arena para el uso de una tabla de calendario. (Es una compulsión)

select count(*) as num_fridays 
from calendar 
where day_of_week = 'Fri' 
    and cal_date between '2011-01-01' and '2011-02-17'; 

num_fridays 
----------- 
6 

Muerto fácil de entender. Aprovecha los índices.

Tal vez debería comenzar un grupo de 12 pasos. Calendario Tabla Anónimo.

+1

+1 para obtener un recordatorio (una vez más) de la utilidad de dicha tabla de calendario. Si solo se instalara una tabla de este tipo por defecto. –

+0

De hecho. El problema parece ser que las personas ven lo que tenemos y eso nos ciega a lo que necesitamos. –

-1
SELECT (NEXT_DAY('31-MAY-2012','SUN') 
-NEXT_DAY('04-MAR-2012','SUN'))/7 FROM DUAL 
+0

La pregunta de los viernes, y la respuesta aceptada más que cubre el mismo terreno con NEXT_DAY – RichardTheKiwi

-1

seleccione ((DATEDIFF (dd, @ a, @ b)) + DATEPART (dw, (@ a-6)))/7

Cuestiones relacionadas