sql >> Databasteknik >  >> RDS >> Sqlserver

Beräkna totala arbetsdagar mellan två datum

Om du bara vill utesluta helger kan du helt enkelt bara utesluta dessa med en villkorad räkning genom att lägga till:

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

Så din fråga blir:

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'

MEN Jag skulle verkligen rekommendera att lägga till en kalendertabell till din databas. Det gör allt så enkelt att din fråga blir:

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';

På så sätt kan du definiera allmänna helgdagar, helger, etc. Det är så mycket mer flexibelt än någon annan lösning.

REDIGERA

Jag tror att jag missförstod dina ursprungliga kriterier. Detta borde fungera för dig utan kalendertabell:

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;


  1. Hur dekrypterar man ett lösenord från SQL-servern?

  2. Hur jämför man programversioner med SQL Server?

  3. Konstruktorn SQLiteOpenHelper() är odefinierad

  4. mysql_close():5 är inte en giltig MySQL-Link-resurs i C:\wamp\www\Includes\footer.php på rad 4