2017-02-22 3 views
0

従業員が会社で働いている期間を調べようとしていますが、辞任したvarcharの値「2年-2月21日」をデータ型intに変換するときに変換に失敗しました

私は今このデータを持っていないので、データベースのこの列の値はNullです。しかし、私はそれが起こったときに自分のSQLで考える退職日の代わりに現在の時間しかし、今は仕事の開始日と現在の時間を取る。私の理論は、列の辞任日付がnullの場合、「現在の日付 - 仕事の開始日」をとり、それ以外の場合は 退職日 - 仕事の開始日。

私はこの理論のためのSQLクエリを書いて、それが正常に働いていますが、私が働いてどのくらいの従業員のための元年月日のリターンをしようとしたとき、私はある問題を抱えて:

A)私は、このエラーで苦戦しました時間と私はまた、これらの行を変換してみました、私はそのを変換する必要があると思ったが、私が私のメインのクエリを実行すると、私はこのエラーを取得し、とてもうまく働いていない:

> 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

- 退職日がnullでない場合は、あなたがdatediffを使用していて、月と日を出力します。 –

答えて

1

case式は単一の値と単一の型を返します。あなたのものは2つの異なる型を返しており、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

2日をたいていない、あなたはそれを書いたが、私はこのエラーを取得:メッセージ241、レベル16、状態を1、Line 1 文字列から日付および/または時刻を変換するときに変換に失敗しました。 – RyaN

+1

'WorkStartDate'のデータ型は何ですか? –

+0

データ型はdatetimeです – RyaN

0

これは何が問題なのですか?

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

何も、私はちょうど元のために、このように私の出して見て、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 year -9 month 8 day」を返します。それはあなたが望んでいたものですか?私の答えは「1年3ヶ月10日」または「1年14週2日」です。 –

関連する問題