Oracle calcula el número de días después de excluir los sábados y domingos en un rango de fechas determinado (licencia, día laborable, tipo de fecha)

Debido a que no me dedico principalmente a operaciones de big data como Oracle, no soy un profesional en la comprensión de declaraciones SQL. Este artículo se utiliza principalmente para registrar mi propia experiencia y proporcionar ideas para la mayoría de los internautas. Si no le gusta mi análisis y explicación, puede omitirlo. , Elimine el SQL que le resulte útil.

 

Al igual que en la pregunta, hay una declaración SQL en el proyecto para calcular el número de días de licencia. Los requisitos generales son:

Dadas las fechas de inicio y finalización de la licencia del empleado, de acuerdo con las condiciones de la consulta (desde la fecha de la consulta y desde la fecha de la consulta), calcule el número real de días de licencia en las condiciones (la clave es que existe la cantidad de días de licencia ingresada por el empleado en el formulario de licencia del empleado) El punto no es muy fácil de usar).

Por ejemplo: la fecha de inicio y finalización de la solicitud de licencia de un empleado es: 2019/07/08, 2019/07/17, la condición de la fecha de consulta es: 2019/07/01, 2019/07/31, luego la solicitud de licencia del empleado durante el período de consulta es 8 día. Este es un ejemplo de caso simple, habrá varios otros casos, que se reflejan en declaraciones SQL.

 

El primer punto: necesitamos conocer el punto más importante, necesitamos juzgar si existe una intersección entre la fecha de licencia del empleado y la fecha de la condición de consulta. Si no existe, significa que no es necesario procesar el registro de licencia del empleado.

El segundo punto: si hay una intersección entre las dos fechas, significa que estos registros deben ser procesados ​​por nosotros. Simplemente lo dividí en las siguientes 3 situaciones (no sé si considerarlo de manera integral).

              El primer caso: la fecha de licencia del empleado incluye la fecha de la condición de consulta. Por ejemplo, la fecha de licencia del empleado: 19/07/01 al 19/07/31, y la fecha de condición de consulta: 19/07/15 al 19/07/21. En este caso, no necesitamos usar la fecha de licencia del empleado, pero podemos usar directamente la fecha de condición de consulta para el cálculo.

              El segundo caso: la fecha de licencia del empleado está dentro de la fecha de la condición de consulta. Esta situación es más fácil de entender Fecha de baja del empleado: 19/07/15 al 19/07/21, y fecha de condición de consulta: 19/07/01 al 19/07/31. En este caso, podemos usar la fecha de licencia del empleado para el cálculo.

              La tercera situación: hay un período de tiempo entre la fecha de licencia del empleado y la fecha de licencia que se cruza con la fecha de la condición de consulta. Esta situación es más complicada y requiere dos métodos de procesamiento. Primero , hay una intersección entre la parte posterior a la fecha de licencia del empleado y la fecha de la condición de consulta, por ejemplo: fecha de licencia del empleado: 19/01/01 al 19/07/21, fecha de la condición de consulta: 19/07/01 al 19/07/31 , La intersección es desde la fecha de la condición de consulta (19/07/01) hasta la fecha de licencia del empleado (19/07/21); En segundo lugar , hay una intersección entre la parte anterior a la fecha de licencia del empleado y la fecha de la condición de consulta, por ejemplo: la fecha de licencia del empleado: 19/07/01 al 19/10/22, fecha de condición de consulta: 19/07/01 al 19/07/31, la intersección es desde la fecha de licencia del empleado (19/07/01) hasta la fecha de condición de consulta (19/07) / 31).

Para ser honesto, creo que es muy complicado, ¿por qué hay tanta demanda fantasma? Busqué en Internet durante mucho tiempo, pero no encontré nada útil.

Continúe, después de analizar estas diversas situaciones, comience a ingresar la instrucción SQL.

Debido a que se calcula para excluir los días hábiles después del sábado y el domingo, encontré un SQL de este tipo en Internet (cambie la hora desde la fecha hasta el final, puede usar directamente la prueba):

select (trunc(to_date(日期止,'yyyy-mm-dd') - to_date(日期起,'yyyy-mm-dd')) - ((
   case WHEN (8 - to_number(to_char(to_date(日期起,'yyyy-mm-dd'),'D'))) > trunc(to_date(日期止,'yyyy-mm-dd') - to_date(日期起,'yyyy-mm-dd')) + 1 THEN 0
         ELSE trunc((trunc(to_date(日期止,'yyyy-mm-dd') - to_date(日期起,'yyyy-mm-dd')) - (8 - to_number(to_char(to_date(日期起,'yyyy-mm-dd'),'D'))))/7) END) + (
   case WHEN mod(8 - to_char(to_date(日期起,'yyyy-mm-dd'), 'D'), 7) > trunc(to_date(日期止,'yyyy-mm-dd') - to_date(日期起,'yyyy-mm-dd')) - 1 THEN 0
         ELSE trunc((trunc(to_date(日期止,'yyyy-mm-dd') - to_date(日期起,'yyyy-mm-dd')) - (mod(8 - to_char(to_date(日期起,'yyyy-mm-dd'),'D'),7) + 1))/7) + 1  END))
	) as workingdays
from dual

Si los lectores quieren comprender este SQL en profundidad, analícelo usted mismo. No soy un profesional y me preocupan los errores de análisis (de hecho, no me molesto en leerlo). De todos modos, funciona.

Entonces, la declaración SQL de solicitud de licencia de mi empleado es la siguiente: (El texto es demasiado, puede copiarlo en Navicat para buscar y reemplazar. Entre ellos, los días de licencia del empleado los completa el propio empleado, principalmente para la situación en la que la licencia del empleado es un número decimal como 0.5. El empleado aquí El inicio y el final de la fecha de la licencia son los campos de la tabla)

SELECT yguuid,username,
sum(CASE WHEN 员工请假日期起 <= TO_DATE(查询条件日期起,'YYYY-MM-DD') and 员工请假日期止 >= TO_DATE(查询条件日期止,'YYYY-MM-DD') THEN (
    trunc(to_date(查询条件日期止,'yyyy-mm-dd') - to_date(查询条件日期起,'yyyy-mm-dd')) - ((
      case WHEN (8 - to_number(to_char(to_date(查询条件日期起,'yyyy-mm-dd'),'D'))) > trunc(to_date(查询条件日期止,'yyyy-mm-dd') - to_date(查询条件日期起,'yyyy-mm-dd')) + 1 THEN 0
        ELSE trunc((trunc(to_date(查询条件日期止,'yyyy-mm-dd') - to_date(查询条件日期起,'yyyy-mm-dd')) -(8 - to_number(to_char(to_date(查询条件日期起,'yyyy-mm-dd'),'D'))))/7) END) + (
      case WHEN mod(8 - to_char(to_date(查询条件日期起,'yyyy-mm-dd'), 'D'), 7) > trunc(to_date(查询条件日期止,'yyyy-mm-dd') - to_date(查询条件日期起,'yyyy-mm-dd')) - 1 THEN 0
        ELSE trunc((trunc(to_date(查询条件日期止,'yyyy-mm-dd') - to_date(查询条件日期起,'yyyy-mm-dd')) - (mod(8 - to_char(to_date(查询条件日期起,'yyyy-mm-dd'),'D'),7) + 1))/7) + 1  END))
)
WHEN 员工请假日期起 >= TO_DATE(查询条件日期起,'YYYY-MM-DD') and 员工请假日期止 <= TO_DATE(查询条件日期止,'YYYY-MM-DD') THEN 员工请假天数 
WHEN 员工请假日期起 <= TO_DATE(查询条件日期起,'YYYY-MM-DD') and 员工请假日期止 <= TO_DATE(查询条件日期止,'YYYY-MM-DD') THEN (
    trunc(to_date(to_char(员工请假日期止,'yyyy-mm-dd'),'yyyy-mm-dd') - to_date(查询条件日期起,'yyyy-mm-dd')) - ((
      case WHEN (8 - to_number(to_char(to_date(查询条件日期起,'yyyy-mm-dd'),'D'))) > trunc(to_date(to_char(员工请假日期止,'yyyy-mm-dd'),'yyyy-mm-dd') - to_date(查询条件日期起,'yyyy-mm-dd')) + 1 THEN 0
        ELSE trunc((trunc(to_date(to_char(员工请假日期止,'yyyy-mm-dd'),'yyyy-mm-dd') - to_date(查询条件日期起,'yyyy-mm-dd')) -(8 - to_number(to_char(to_date(查询条件日期起,'yyyy-mm-dd'),'D'))))/7) END) + (
      case WHEN mod(8 - to_char(to_date(查询条件日期起,'yyyy-mm-dd'), 'D'), 7) > trunc(to_date(to_char(员工请假日期止,'yyyy-mm-dd'),'yyyy-mm-dd') - to_date(查询条件日期起,'yyyy-mm-dd')) - 1 THEN 0
        ELSE trunc((trunc(to_date(to_char(员工请假日期止,'yyyy-mm-dd'),'yyyy-mm-dd') - to_date(查询条件日期起,'yyyy-mm-dd')) - (mod(8 - to_char(to_date(查询条件日期起,'yyyy-mm-dd'),'D'),7) + 1))/7) + 1  END))
)
WHEN 员工请假日期起 >= TO_DATE(查询条件日期起,'YYYY-MM-DD') and 员工请假日期止 >= TO_DATE(查询条件日期止,'YYYY-MM-DD') THEN (
    trunc(to_date(查询条件日期止,'yyyy-mm-dd') - to_date(to_char(员工请假日期起,'yyyy-mm-dd'),'yyyy-mm-dd')) - ((
      case WHEN (8 - to_number(to_char(to_date(to_char(员工请假日期起,'yyyy-mm-dd'),'yyyy-mm-dd'),'D'))) > trunc(to_date(查询条件日期止,'yyyy-mm-dd') - to_date(to_char(员工请假日期起,'yyyy-mm-dd'),'yyyy-mm-dd')) + 1 THEN 0
        ELSE trunc((trunc(to_date(查询条件日期止,'yyyy-mm-dd') - to_date(to_char(员工请假日期起,'yyyy-mm-dd'),'yyyy-mm-dd')) -(8 - to_number(to_char(to_date(to_char(员工请假日期起,'yyyy-mm-dd'),'yyyy-mm-dd'),'D'))))/7) END) + (
      case WHEN mod(8 - to_char(to_date(to_char(员工请假日期起,'yyyy-mm-dd'),'yyyy-mm-dd'), 'D'), 7) > trunc(to_date(查询条件日期止,'yyyy-mm-dd') - to_date(to_char(员工请假日期起,'yyyy-mm-dd'),'yyyy-mm-dd')) - 1 THEN 0
        ELSE trunc((trunc(to_date(查询条件日期止,'yyyy-mm-dd') - to_date(to_char(员工请假日期起,'yyyy-mm-dd'),'yyyy-mm-dd')) - (mod(8 - to_char(to_date(to_char(员工请假日期起,'yyyy-mm-dd'),'yyyy-mm-dd'),'D'),7) + 1))/7) + 1  END))
)
END) qjts 
from xmgl_ygqjxx WHERE (员工请假日期起 <= TO_DATE(查询条件日期止,'YYYY-MM-DD') and 员工请假日期止 >= TO_DATE(查询条件日期起,'YYYY-MM-DD')) GROUP BY yguuid,username

Si tiene alguna pregunta, deje un mensaje. . . .

Supongo que te gusta

Origin blog.csdn.net/FV8023/article/details/95194067
Recomendado
Clasificación