【问题标题】:Need to get working days of an employee需要获取员工的工作日
【发布时间】:2018-03-07 03:58:39
【问题描述】:

我想根据年份和月份参数获取员工的工作日(不包括周六和周日)。如果我选择年份参数,那么它应该是从 2018/01/01 到今天的日期,他工作了多少天。如果我选择月份参数,那么这个月三月份有多少个工作日。

以下是我对年份参数的查询

DECLARE 
    @MONTH NVARCHAR(100) = NULL,
    @YEAR NVARCHAR(200) = NULL

SET @MONTH = NULL
SET @YEAR = 2018;

WITH CTE
AS (
    SELECT *
    FROM (
        SELECT E.EmployeeId AS ID,
            E.Name AS 'NAME',
            EL.EntitlementStart,
            EL.EntitlementEnd,
            EL.LeaveTypeId AS 'LEAVE TYPE',
            CASE 
                WHEN EL.EntitlementEnd < getdate()
                    THEN datediff(day, EL.EntitlementStart, EL.EntitlementEnd)
                        --WHEN @MONTH IS NULL OR @MONTH=''AND @YEAR IS NOT NULL AND @YEAR<>'' AND EL.EntitlementStart <= GETDATE() AND YEAR(EL.EntitlementStart)=@YEAR AND DATEPART(WEEKDAY,EL.EntitlementStart) != 1 AND DATEPART(WEEKDAY,EL.EntitlementStart) != 7 THEN
                WHEN EL.EntitlementStart > getdate()
                    THEN NULL
                ELSE datediff(day, EL.EntitlementStart, getdate())
                END AS 'NumberofDays',
            (EL.EntitledAmount - EL.RemainingAmount) AS 'LEAVE TAKEN'
        FROM Entitlements EL
        INNER JOIN Employees E ON E.EmployeeId = EL.Employee_EmployeeId
        WHERE LeaveTypeId IN ('AL', 'MC', 'TRG')
    ) AS S
    PIVOT(SUM([LEAVE TAKEN]) FOR [LEAVE TYPE] IN (AL, MC, TRG)) AS pvt
)

SELECT *
INTO #TEMPSUMMARY
FROM CTE

--select * from #TEMPSUMMARY
IF (@MONTH IS NULL OR @MONTH = '') AND (@YEAR IS NOT NULL AND @YEAR <> '')
BEGIN
    SELECT *
    FROM #TEMPSUMMARY A
    WHERE YEAR(A.EntitlementStart) = @YEAR AND A.EntitlementStart <= GETDATE() AND DATEPART(WEEKDAY, A.EntitlementStart) != 1 AND DATEPART(WEEKDAY, A.EntitlementStart) != 7
END

IF (@MONTH IS NOT NULL AND @MONTH <> '') AND (@YEAR IS NULL OR @YEAR = '')
BEGIN
    SELECT COUNT(A.EntitlementStart)
    FROM #TEMPSUMMARY A
    WHERE A.EntitlementStart BETWEEN DATEADD(DAY, - GETDATE() + 1, GETDATE())
            AND GETDATE() AND DATEPART(WEEKDAY, A.EntitlementStart) != 1 AND DATEPART(WEEKDAY, A.EntitlementStart) != 7
END

【问题讨论】:

  • 最好有一个日期表(包括快速访问的信息,例如,是否是周末 - 例如,mssqltips.com/sqlservertip/4054/…)和一个公共假期表以供查询像这样。
  • 是的,但目前没有周末的桌子,只有公共假期我们有桌子。我已经有查询条件排除公共假期的
  • 我建议你也开始使用正确的数据类型(年份和月份似乎是一个标志,但你使用的是 nvarchar(100))并且绝对缩进你的代码,这真的很难阅读
  • 当然,James,Inside Stored Proc 我会给出正确的数据类型。

标签: sql sql-server reporting-services ssrs-2012


【解决方案1】:

我们可以使用CTE 来解决这个问题-

declare @YEAR bit = 0
declare @MONTH bit = 1
declare @StartDT datetime = (case when isnull(@YEAR,0) <> 0 then '2018-01-01' else dateadd(month, datediff(month, 0, getdate()), 0) end)

;with cte as
(
    select @StartDT as StartDT, DATEPART(WEEKDAY, @StartDT) as [WeekDay]
    union all
    select DATEADD(DD, 1, StartDT),DATEPART(WEEKDAY,DATEADD(DD, 1, StartDT))
    from cte
    where StartDT < getdate()-1
)
select count(distinct StartDT)
from cte
where [WeekDay] not in (1,7)

更改@YEAR@MONTH 的位值以进行测试。

【讨论】:

    【解决方案2】:

    据我了解,如果选择了月份,我们需要计算当前月份的工作日数,如果选择了相应的年份,则需要计算当前年份的工作日数,直到今天。对于此要求,您可以按照以下代码进行操作:

    IF(ISNULL(@Month,0)=0 AND ISNULL(@Year,0)!=0)
    BEGIN
       SELECT COUNT(Date_Col)
       FROM Table_Name
       WHERE YEAR(Date_Col)=@Year AND Date_Col <= GETDATE() AND DATEPART(WEEKDAY,Date_Col) != 1 AND DATEPART(WEEKDAY,Date_Col) != 7
    END
    
    IF(ISNULL(@Year,0)=0 AND ISNULL(@Month)!=0)
    BEGIN
       SELECT COUNT(Date_Col)
       FROM Table_Name
       WHERE Date_Col BETWEEN DATEADD(DAY,-GETADATE()+1,GETDATE()) AND GETDATEE() AND DATEPART(WEEKDAY,Date_Col) != 1 AND DATEPART(WEEKDAY,Date_Col) != 7
    

    希望您找到了您的需求。

    如果有什么问题请告诉我。

    【讨论】:

    • 查询是否满足您的要求??或至少为您的解决方案提供任何想法
    • 我已经编辑了查询(在我的帖子中),但它仍然给了我计数而不扣除星期六和太阳(周末),我想我的天数列我应该包含一些逻辑来过滤掉坐着和太阳。
    • 但是 WHERE 子句完全可以过滤周末,​​我希望我们需要照顾 CTE 你确定你构建的 CTE 吗?如果不是,请验证。
    猜你喜欢
    • 1970-01-01
    • 2021-10-01
    • 2021-12-14
    • 2016-04-20
    • 2019-03-14
    • 2016-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多