2017-02-22 66 views
0

我想了解员工为公司工作了多长时间,我还应该了解是否有员工有一个辞职日期。将varchar值'2 year -2 month 21 day'转换为数据类型int时的转换失败

但是我现在没有这个数据,因此我的数据库中该列的值为空。但我认为在我的SQL发生时,采取辞职日期,而不是当前时间但现在采取工作开始日期和当前时间。我的理论是,如果列辞职日期为空,采取“当前日期 - 工作开始日期”,否则 它应该采取辞职日期 - 工作开始日期。

我写了一个SQL查询这个理论,它的工作很好,但是当我试图为前一年一个月一天回到了我的员工如何长的工作得到了一个问题,就是:

一)我这个错误的挣扎小时,我也尝试过转换的思路,我认为它应该被转换,但它不工作舒服,所以,当我跑我的主查询,我得到这个错误:

> Msg 245, Level 16, State 1, Line 1 
> Conversion failed when converting the varchar value '2 year -2 month 21 day' to data type int. 

我的主查询看起来是这样的:

**--- sql for how long employees work with year month day ----** 
    CASE 
     WHEN Users.ResignationDate IS NOT NULL 
      THEN DATEDIFF(YEAR, WorkStartDate, ResignationDate) 
      ELSE CAST(DATEDIFF(yy, WorkStartDate, GETDATE()) AS varchar(4)) + ' year ' + 
       CAST(DATEDIFF(mm, DATEADD(yy, DATEDIFF(yy, WorkStartDate, GETDATE()), WorkStartDate), GETDATE()) AS varchar(2)) + ' month ' + 
       CAST(DATEDIFF(dd, DATEADD(mm, DATEDIFF(mm, DATEADD(yy, DATEDIFF(yy, WorkStartDate, GETDATE()), WorkStartDate), GETDATE()), DATEADD(yy, DATEDIFF(yy, WorkStartDate, GETDATE()), WorkStartDate)), GETDATE()) AS varchar(2)) +' day' END as Ancinitet, 
     Paychecks.DepartmentName AS Afdelinger 
    FROM dbo.Paychecks INNER JOIN dbo.Users ON Users.Id=Paychecks.UserId 
WHERE Users.CustomerId=214 order by Users.FirstName; 
+0

我建议简化查询隔离问题。 –

+0

我刚刚编辑了查询,请看看,如果不行,请告诉我 – RyaN

+0

为什么你在两种情况下显示不同的结果 - 当辞职日期不为空时,你使用的是datediff,当为空时,月和日的输出。 –

回答

1

A case表达式返回单个值 - 和单一类型。你的返回两种不同的类型,并且SQL Server决定适当的返回类型是第一个,一个整数。

只是转换为字符串:

(CASE WHEN Users.ResignationDate IS NOT NULL 
     THEN CAST(DATEDIFF(YEAR, WorkStartDate, ResignationDate) as VARCHAR(255)) 
     ELSE (CAST(DATEDIFF(year, WorkStartDate, GETDATE()) AS varchar(4)) +' year ' + 
      CAST(DATEDIFF(month, DATEADD(year, DATEDIFF(year, WorkStartDate, GETDATE()), WorkStartDate), GETDATE()) AS varchar(2)) +' month ' + 
      CAST(DATEDIFF(day, DATEADD(month, DATEDIFF(month, DATEADD(year, DATEDIFF(year, WorkStartDate, GETDATE()), WorkStartDate), GETDATE()), DATEADD(year, DATEDIFF(yy, WorkStartDate, GETDATE()), WorkStartDate)), GETDATE()) AS varchar(2)) +' day' 
     ) 
END) as Ancinitet, 

我怀疑有一个更好的方式做你想做的。如果有兴趣,请询问另一个问题与样品数据和期望的结果。

+0

我刚取代了代码,你写了但我得到这个错误:Msg 241,Level 16,State 1,第1行 从字符串中转换日期和/或时间时转换失败。 – RyaN

+1

“WorkStartDate”的数据类型是什么? –

+0

资料类型是datetime – RyaN

0

这是怎么回事?

datediff(year, workStartDate, isNull(resignationDate, getDate())) 
+0

没有什么不对,那我只是想让我看起来像这样对于前,2年2个月2天 – RyaN

0

使用周而不是几个月会更好,因为一周总是包含7天。你也可以使用30天的月份,这通常会让你关闭,但你的日子可能会被一对夫妇关闭。

DECLARE @StartDate DATETIME = '20151115', 
     @EndDate DATETIME = GETDATE(); 

SELECT YearWeekDay = CONCAT(DATEDIFF(DAY, @StartDate, @EndDate)/365, ' year ', DATEDIFF(DAY, @StartDate, @EndDate) % 365/7, ' week ', 
           DATEDIFF(DAY, @StartDate, @EndDate) % 365 % 7, ' day' 
          ), 
     YearMonthDay = CONCAT(DATEDIFF(DAY, @StartDate, @EndDate)/365, ' year ', DATEDIFF(DAY, @StartDate, @EndDate) % 365/30, ' month ', 
           DATEDIFF(DAY, @StartDate, @EndDate) % 365 % 30, ' day ' 
          ), 
     YWDHMS = CONCAT(DATEDIFF(SECOND, @StartDate, @EndDate)/86400/365, 'y ', DATEDIFF(SECOND, @StartDate, @EndDate)/86400 % 365/7, 'w ', 
         DATEDIFF(SECOND, @StartDate, @EndDate)/86400 % 365 % 7, 'd ', DATEDIFF(SECOND, @StartDate, @EndDate) % 86400/3600, 'h ', 
         DATEDIFF(SECOND, @StartDate, @EndDate) % 3600/60, 'm ', DATEDIFF(SECOND, @StartDate, @EndDate) % 60, 's ' 
         ); 

输出:

StartDate EndDate     YearWeekDay    YearMonthDay   YWDHMS 
2015-11-15 2017-02-22 15:11:34.123 1 year 14 week 2 day 1 year 3 month 10 day 1y 14w 2d 15h 11m 34s 
+0

@RyaN您接受的答案于2015年11月15日返回“2年-9个月8天”。那是你想要的吗?我的答案返回“1年3个月10天”或“1年14周2天”。 –

相关问题