Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Berechnen Sie die Gesamtarbeitstage zwischen zwei Daten

Wenn Sie nur Wochenenden ausschließen möchten, können Sie diese einfach mithilfe einer bedingten Zählung ausschließen, indem Sie Folgendes hinzufügen:

count(distinct case when datepart(weekday, getdate()) <= 5 then date end)

Ihre Abfrage wird also:

set datefirst 1;

select  count(distinct(dateadd(d, 0, datediff(d, 0,checktime)))) as workingdays,
        count(distinct case when datepart(weekday, getdate()) <= 5 
                            then dateadd(d, 0, datediff(d, 0,checktime)) 
                        end) as weekdays
from departments,
 dbo.USERINFO INNER JOIN dbo.CHECKINOUT ON 
     dbo.USERINFO.USERID = dbo.CHECKINOUT.USERID
where  userinfo.name='Gokul Gopalakrishnan' and deptname='GEN/SUP-TBL' 
and checktime>='2014-05-01' and checktime<='2014-05-30'

JEDOCH Ich würde wirklich empfehlen, einen Kalendertabelle zu Ihrer Datenbank. Es macht alles so einfach, dass Ihre Abfrage folgendermaßen aussehen würde:

SELECT  DaysWorked = COUNT(cio.Date),
        WeekDaysWorked = COUNT(CASE WHEN c.IsWeekDay = 1 THEN cio.Date END),
        WorkingDaysWorked = COUNT(CASE WHEN c.IsWorkingDay = 1 THEN cio.Date END),
        TotalDays = COUNT(*),
        TotalWeekDays = COUNT(CASE WHEN c.IsWeekDay = 1 THEN 1 END),
        TotalWorkingDays = COUNT(CASE WHEN c.IsWorkingDay = 1 THEN 1 END)
FROM    dbo.Calender AS c
        LEFT JOIN
        (   SELECT  DISTINCT
                    Date = CAST(CheckTime AS DATE)
            FROM    dbo.Departments AS d
                    CROSS JOIN dbo.userInfo AS ui
                    INNER JOIN dbo.CheckInOut AS cio
                        ON cio.UserID = ui.UserID
            WHERE   ui.Name = 'Gokul Gopalakrishnan' 
            AND     d.deptname = 'GEN/SUP-TBL' 
        ) AS cio
            ON c.Date = cio.Date
WHERE   d.Date >= '2014-05-01'
AND     d.Date <= '2014-05-30';

Auf diese Weise können Sie Feiertage, Wochenenden usw. definieren. Es ist so viel flexibler als jede andere Lösung.

BEARBEITEN

Ich glaube, ich habe Ihre ursprünglichen Kriterien falsch verstanden. Dies sollte für Sie ohne Kalendertabelle funktionieren:

SET DATEFIRST 1;

DECLARE @StartDate DATE = '2014-05-01', 
        @EndDate DATE = '2014-05-30';

DECLARE @Workdays INT = 
    (DATEDIFF(DAY, @StartDate, @EndDate) + 1)
    -(DATEDIFF(WEEK, @StartDate, @EndDate) * 2)
    -(CASE WHEN DATEPART(WEEKDAY, @StartDate) = 7 THEN 1 ELSE 0 END)
    -(CASE WHEN DATEPART(WEEKDAY, @EndDate) = 6 THEN 1 ELSE 0 END);


SELECT  WorkingDays = COUNT(DISTINCT CAST(CheckTime AS DATE)),
        BusinessDays = @Workdays
FROM    dbo.Departments AS d
        CROSS JOIN dbo.userInfo AS ui
        INNER JOIN dbo.CheckInOut AS cio
            ON cio.UserID = ui.UserID
WHERE   ui.Name = 'Gokul Gopalakrishnan' 
AND     d.deptname = 'GEN/SUP-TBL' 
AND     cio.CheckTime >= @StartDate
AND     cio.CheckTime <= @EndDate;