2014-07-02 22 views
0
SELECT DISTINCT (DATEDIFF(DAY, '2014-06-01', '2014-06-30') + 1) - DATEDIFF(WEEK, '2014-06-01', '2014-06-30') * 2 - (CASE WHEN DATEPART(WEEKDAY, '2014-06-01') = 5 THEN 1 ELSE 0 END) - (CASE WHEN DATEPART(WEEKDAY, '2014-06-30') = 6 THEN 1 ELSE 0 END) AS TotalWorkingDays, COUNT(DISTINCT DATEADD(d, 0,DATEDIFF(d, 0, CHECKINOUT.CHECKTIME))) AS workingdays, 
USERINFO.NAME, 
case when '08:00:00.000' > cast(convert(char(8),min(checktime),8) as datetime) THEN NULL 
ELSE 
cast(dateadd(minute,datediff(minute,'08:00:00.000',min(checktime)),'00:00')AS dateTIME) END as LATEIN , 
case when '17:00:00.000' < cast(convert(char(8),max(checktime),8) as datetime) THEN NULL 
ELSE 
cast(dateadd(minute,datediff(minute,max(checktime),'17:00:00.000'),'00:00')AS dateTIME)END as LATEOUT  
FROM USERINFO left JOIN CHECKINOUT ON CHECKINOUT.USERID = USERINFO.USERID 
left join departments on deptid = userinfo.DEFAULTDEPTID 
WHERE(DEPARTMENTS.DEPTNAME = 'GEN/SUP-TBL') AND (CHECKINOUT.CHECKTIME >='2014-06-01') AND (CHECKINOUT.CHECKTIME <='2014-06-30') and name='Gokul Gopalakrishnan' 
GROUP BY USERINFO.NAME,checktime 

这是我的查询上的时间的价值和它给了以下的输出:我要总结的SQL服务器

TotalWorkingDays workingdays NAMER LATEIN       LATEOUT 
22     1   abc  NULL     1785-07-17 09:24:00.000 
22     1   abc  NULL     1785-07-18 00:15:00.000 
22     1   abc  NULL     1785-07-31 00:30:00.000 
22     1   abc 2014-06-01 00:39:00.000 1785-08-02 01:00:00.000 
22     1   abc 2014-06-01 09:14:00.000  NULL 

但现在我想输出象下面这样:

TotalWorkingDays workingdays NAME TOTAL LATEIN  TOTAL LATEOUT 
22     5   abc  09:53:00.000  10:69:00.000 

有没有办法做到这一点?

+1

有没有办法做到这一点???? * YES!*它涉及字符串操作来解析出围绕“:”的每个段,然后将每个段相加,然后重新构建一个新的字符串输出。你知道每个值的长度是一致的,所以将其转换为字符串,将其分配到各个元素中,然后添加这些结果,然后构建输出字符串。但为什么在地球上...有人会想这样做... – xQbert

+2

它看起来像一个重复的问题:看到这个http://stackoverflow.com/questions/13991440/sum-of-datetime-difference-in-sql- hh-mm Regards, –

+0

@xQbert。我没有得到它....请你帮我..? –

回答

2

FULL后处理:

  1. 我们第一时间转换为字符串格式所需的输出。使用convert(nvarchar(50),time,121)
  2. 然后,我们将每个时间集进行子串排序,以便它们可以相加在一起。
  3. 此前总结我们要投的字符串返回数值
  4. 现在,我们有我们必须确保正确领导0填充右边的总和(00 +转换...)

所得在: 。

Select 
    TotalWorkingDays, 
    sum(workingDays) as WorkingDays, 
    Namer, 
    right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateIn,121),12,2) as Numeric(2,0)))),2)+ ':'+ 
    right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateIn,121),15,2) as Numeric(2,0)))),2)+ ':'+  
    right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateIn,121),18,2) as Numeric(2,0)))),2)+ ':'+  
    right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateIn,121),21,3) as Numeric(3,0)))),3) as LateIn, 
    right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateOut,121),12,2) as Numeric(2,0)))),2)+ ':'+ 
    right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateOut,121),15,2) as Numeric(2,0)))),2)+ ':'+  
    right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateOut,121),18,2) as Numeric(2,0)))),2)+ ':'+  
    right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateOut,121),21,3) as Numeric(3,0)))),3) as LateOut 
from blue 
Group by TotalWorkingDays, namer 

使用本例 http://sqlfiddle.com/#!3/81c0c/2/0

这具有显著问题然而

假设求和小时,分或秒超过2位数字。你的53是... 100 ...应该发生什么?目前这只能看到最右边的两个角色会发生什么?

您的输出不能是日期时间数据类型,因为69不是有效的分钟...正如在10:69:00.000中一样,因此输出;所以要么输出是varchar,要么你的预期结果不正确。

现在整合现有查询:

With CTE as (
SELECT DISTINCT (DATEDIFF(DAY, '2014-06-01', '2014-06-30') + 1) - DATEDIFF(WEEK, '2014-06-01', '2014-06-30') * 2 - (CASE WHEN DATEPART(WEEKDAY, '2014-06-01') = 5 THEN 1 ELSE 0 END) - (CASE WHEN DATEPART(WEEKDAY, '2014-06-30') = 6 THEN 1 ELSE 0 END) AS TotalWorkingDays, COUNT(DISTINCT DATEADD(d, 0,DATEDIFF(d, 0, CHECKINOUT.CHECKTIME))) AS workingdays, 
USERINFO.NAME, 
case when '08:00:00.000' > cast(convert(char(8),min(checktime),8) as datetime) THEN NULL 
ELSE 
cast(dateadd(minute,datediff(minute,'08:00:00.000',min(checktime)),'00:00')AS dateTIME) END as LATEIN , 
case when '17:00:00.000' < cast(convert(char(8),max(checktime),8) as datetime) THEN NULL 
ELSE 
cast(dateadd(minute,datediff(minute,max(checktime),'17:00:00.000'),'00:00')AS dateTIME)END as LATEOUT  
FROM USERINFO left JOIN CHECKINOUT ON CHECKINOUT.USERID = USERINFO.USERID 
left join departments on deptid = userinfo.DEFAULTDEPTID 
WHERE(DEPARTMENTS.DEPTNAME = 'GEN/SUP-TBL') AND (CHECKINOUT.CHECKTIME >='2014-06-01') AND (CHECKINOUT.CHECKTIME <='2014-06-30') and name='Gokul Gopalakrishnan' 
GROUP BY USERINFO.NAME,checktime) 
    Select 
     TotalWorkingDays, 
     sum(workingDays) as WorkingDays, 
     Namer, 
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateIn,121),12,2) as Numeric(2,0)))),2)+ ':'+ 
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateIn,121),15,2) as Numeric(2,0)))),2)+ ':'+  
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateIn,121),18,2) as Numeric(2,0)))),2)+ ':'+  
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateIn,121),21,3) as Numeric(3,0)))),3) as LateIn, 
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateOut,121),12,2) as Numeric(2,0)))),2)+ ':'+ 
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateOut,121),15,2) as Numeric(2,0)))),2)+ ':'+  
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateOut,121),18,2) as Numeric(2,0)))),2)+ ':'+  
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateOut,121),21,3) as Numeric(3,0)))),3) as LateOut 
    from CTE 
    Group by TotalWorkingDays, namer 

还是老fassion方式...

Select 
     TotalWorkingDays, 
     sum(workingDays) as WorkingDays, 
     Namer, 
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateIn,121),12,2) as Numeric(2,0)))),2)+ ':'+ 
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateIn,121),15,2) as Numeric(2,0)))),2)+ ':'+  
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateIn,121),18,2) as Numeric(2,0)))),2)+ ':'+  
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateIn,121),21,3) as Numeric(3,0)))),3) as LateIn, 
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateOut,121),12,2) as Numeric(2,0)))),2)+ ':'+ 
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateOut,121),15,2) as Numeric(2,0)))),2)+ ':'+  
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateOut,121),18,2) as Numeric(2,0)))),2)+ ':'+  
     right('00'+convert(varchar,sum(cast(substring(convert(nvarchar(50),LateOut,121),21,3) as Numeric(3,0)))),3) as LateOut 
    from (
    SELECT DISTINCT (DATEDIFF(DAY, '2014-06-01', '2014-06-30') + 1) - DATEDIFF(WEEK, '2014-06-01', '2014-06-30') * 2 - (CASE WHEN DATEPART(WEEKDAY, '2014-06-01') = 5 THEN 1 ELSE 0 END) - (CASE WHEN DATEPART(WEEKDAY, '2014-06-30') = 6 THEN 1 ELSE 0 END) AS TotalWorkingDays, COUNT(DISTINCT DATEADD(d, 0,DATEDIFF(d, 0, CHECKINOUT.CHECKTIME))) AS workingdays, 
    USERINFO.NAME, 
    case when '08:00:00.000' > cast(convert(char(8),min(checktime),8) as datetime) THEN NULL 
    ELSE 
    cast(dateadd(minute,datediff(minute,'08:00:00.000',min(checktime)),'00:00')AS dateTIME) END as LATEIN , 
    case when '17:00:00.000' < cast(convert(char(8),max(checktime),8) as datetime) THEN NULL 
    ELSE 
    cast(dateadd(minute,datediff(minute,max(checktime),'17:00:00.000'),'00:00')AS dateTIME)END as LATEOUT  
    FROM USERINFO left JOIN CHECKINOUT ON CHECKINOUT.USERID = USERINFO.USERID 
    left join departments on deptid = userinfo.DEFAULTDEPTID 
    WHERE(DEPARTMENTS.DEPTNAME = 'GEN/SUP-TBL') AND (CHECKINOUT.CHECKTIME >='2014-06-01') AND (CHECKINOUT.CHECKTIME <='2014-06-30') and name='Gokul Gopalakrishnan' 
    GROUP BY USERINFO.NAME,checktime) blue 
    Group by TotalWorkingDays, namer 
+0

它给出了以下错误: 参数数据类型datetime对于子字符串函数的参数1无效。 –

+0

它仍然给出相同的错误:参数数据类型datetime对子字符串函数的参数1无效。 –

+0

仍然给出相同的错误...你已经使用varchar,但有datetime数据类型... –