我需要为每个用户获取他们一周中的多少天(一个月),我有一个表来存储他们不工作的日期范围(病假),还有一个统计表来存储工作日。
ausentismoT将非工作日存储为日期范围,该表如下所示
user ini fin --ini = start date | fin = end date
---------------------------
john 06/05/2019 06/05/2019
john 13/05/2019 13/05/2019
john 20/05/2019 24/05/2019
理货表格,存储每月的每一天并将其状态标记为假期:
IDCal fechaValor numDiaSemana nomDia nomMes semanaAno diaJuliano feriadoBancario feriadoNombre
---------------------------------------------------------------------------------------------
20190502 2019-05-02 00:00:00.000 4 Jueves Mayo 18 122 0 NULL
20190503 2019-05-03 00:00:00.000 5 Viernes Mayo 18 123 0 NULL
20190504 2019-05-04 00:00:00.000 6 Sábado Mayo 18 124 1 Weekend
我的代码,在我知道逻辑错误的情况下,我“尝试”排除假日和非工作日,但所有列的结果均为0:
SELECT T.RUT_DV,
T.USER,
DIAS_HAB_MES = (SELECT COUNT(CONVERT(INT,feriadoBancario,112)) AS D FROM CALENDAR C WHERE feriadoBancario=0 AND CONVERT(NVARCHAR(6),C.fechaValor,112) = CONVERT(NVARCHAR(6),GETDATE(),112)),
LUNES = (SELECT COUNT(CONVERT(INT,feriadoBancario,112)) AS D FROM CALENDAR C
WHERE numDiaSemana=1 AND feriadoBancario = 0 AND (FECHAVALOR BETWEEN DATEADD(MM, DATEDIFF(MM, 0, GETDATE())-1, 0) AND T2.INI) AND FECHAVALOR BETWEEN DATEADD(MM, DATEDIFF(MM, 0, getdate()), 0)-1 AND T2.FIN),
MARTES = (SELECT COUNT(CONVERT(INT,feriadoBancario,112)) AS D FROM CALENDAR C
WHERE numDiaSemana=2 AND feriadoBancario = 0 AND (FECHAVALOR BETWEEN DATEADD(MM, DATEDIFF(MM, 0, GETDATE())-1, 0) AND T2.INI) AND FECHAVALOR BETWEEN DATEADD(MM, DATEDIFF(MM, 0, getdate()), 0)-1 AND T2.FIN),
MIERCOLES = (SELECT COUNT(CONVERT(INT,feriadoBancario,112)) AS D FROM CALENDAR C
WHERE numDiaSemana=3 AND feriadoBancario = 0 AND (FECHAVALOR BETWEEN DATEADD(MM, DATEDIFF(MM, 0, GETDATE())-1, 0) AND T2.INI) AND FECHAVALOR BETWEEN DATEADD(MM, DATEDIFF(MM, 0, getdate()), 0)-1 AND T2.FIN),
JUEVES = (SELECT COUNT(CONVERT(INT,feriadoBancario,112)) AS D FROM CALENDAR C
WHERE numDiaSemana=4 AND feriadoBancario = 0 AND (FECHAVALOR BETWEEN DATEADD(MM, DATEDIFF(MM, 0, GETDATE())-1, 0) AND T2.INI) AND FECHAVALOR BETWEEN DATEADD(MM, DATEDIFF(MM, 0, getdate()), 0)-1 AND T2.FIN),
VIERNES = (SELECT COUNT(CONVERT(INT,feriadoBancario,112)) AS D FROM CALENDAR C
WHERE numDiaSemana=5 AND feriadoBancario = 0 AND (FECHAVALOR BETWEEN DATEADD(MM, DATEDIFF(MM, 0, GETDATE())-1, 0) AND T2.INI) AND FECHAVALOR BETWEEN DATEADD(MM, DATEDIFF(MM, 0, getdate()), 0)-1 AND T2.FIN)
FROM dotacionAD T -- BASE TABLE
LEFT JOIN ausentismoT T2 ON T.RUT_DV = REPLACE(T2.RUT_DV,'.','')
结果是这样的
NOM_COL DIAS_HAB_MES LUNES MARTES MIERCOLES JUEVES VIERNES
-------------------------------------------------------------------
JOHN 20 0 0 0 0 0
对于相同的情况,应显示以下内容:
NOM_COL DIAS_HAB_MES LUNES MARTES MIERCOLES JUEVES VIERNES
-------------------------------------------------------------------
JOHN 20 1 3 3 4 4
答案 0 :(得分:0)
我相信您第二次复制粘贴dateadd / datediff时发生了错误。
在我编写此答案时,我的本地getdate()将在2019年6月6日返回。
您的第一个条件是:
FECHAVALOR BETWEEN DATEADD(MM, DATEDIFF(MM, 0, GETDATE())-1, 0) AND T2.INI
此公式将当前日期截断为月级别,并且还减去一个月。因此,如果我现在运行它,我将在2019年5月1日得到回报。您所有的ini都在此之后,所以确定。
您的第二个条件是:
FECHAVALOR BETWEEN DATEADD(MM, DATEDIFF(MM, 0, getdate()), 0)-1 AND T2.FIN
此公式将当前日期截断为月级别,不不减去一个月,但最后减去一天。因此,如果我现在运行它,我将在2019年6月2日得到回报。您的鳍片都不会迟于此,这就是为什么您到处都为零的原因。
现在我不确定您打算看到什么,但是两个BETWEEN
似乎很奇怪。如果您想使用ausentismoT
中的最近两个月,则可以这样写:
FECHAVALOR >= DATEADD(MM, DATEDIFF(MM, 0, GETDATE())-1, 0)
AND
FECHAVALOR BETWEEN T2.INI and T2.FIN
答案 1 :(得分:0)
这应该有助于您入门。尚不清楚您是否提供了所有信息。
select
t.user, count(*) as dia_hab_mes,
count(case when numDiaSemana = 1 then 1 end) as lunes,
...
from
users as u cross join calendar as c
left outer join ausentismoT as a
on c.<date> between a.ini and a.fin and a.user = t.user
where c.<date> ... /* filter dates for desired month */
and feriadoBancario = 0
group by u.user;