2017-11-27 3 views
0

저는 SQL 전문가가 아니며이를 파악하는 데 도움이 필요합니다. 필자는 사용자가 펀치 한 시간을 추적하고 작업 시간 및 기타 계산 시간을 계산할 필요가있는 SQL Server 2012 데이터베이스가있는 급여 응용 프로그램을 작성하고 있습니다. 근무 시간은 오전 9시 30 분에서 오후 5시 30 분 사이의 시간으로 계산됩니다. 여기에 논리입니다 :SQL Server는 Select 문에 조건부 변수를 할당합니다.

  • 이전의 오전 9시 반에서 사용자 펀치는, 작업 시작 시간은 오전 9시 반
  • 에 를 설정하면 나중에보다 오전 9:30 작업 시작의 사용자 펀치하면 실제 시간은 입니다.
  • 사용자가 오후 5시 30 분 이후에 펀치 아웃하는 경우. 작업 종료 시간은 오후 5시 30 분으로 으로 설정됩니다.
  • 사용자가 오후 5시 30 분 전에 펀치 아웃하는 경우 작업 종료 시간은 으로 실제 펀치 아웃 시간으로 설정됩니다.

여기서 부분적인 SQL은 시도했지만 어디에도 없습니다. 어떤 도움을 주시면 감사하겠습니다 :

declare @start time; 
declare @end time; 
select @start=cast('09:30:00.0000000' as time) 
select @end=cast('17:30:00.0000000' as time) 
    SELECT Datename(dw,LastUpdate) as WeekDay 
    ,FORMAT(PunchIn,'MM/dd/yyyy hh:mm tt') as PunchIn 
    ,FORMAT(PunchOut,'MM/dd/yyyy hh:mm tt') as PunchOut 
    ,case 
     --employee punched in before 9:30 so take 9:30 as start time 
     when datediff(mi,@start,cast(PunchIn as time))<0 then (select @start='09:30:00.0000000') end 
    from TimeTracker 

이 전체 SQL 아니지만 당신은 내가 사용하려고 논리를 볼 수 있습니다. 내 질문은 펀치 인 또는 펀치 아웃 시간과 같은 다른 열의 값을 기준으로 시작 시간 또는 종료 시간을 설정하는 방법입니다. SQL은 select 절에서 when 절의 일부로 오류를 제공합니다. 다른 언어에서는 쉽게이 작업을 수행 할 수 있지만 SQL에서는 어려움을 겪고 있습니다.

+0

'(@ start = '09 : 30 : 00.0000000') '을 (를) 선택하고 '09 : 30 : 00.0000000'또는 '더 나은'then @ start '로 변경해보십시오 – Beth

답변

0

거의 다 왔어! 수정 된 SQL 코드는 다음과 같습니다. CASE stmt의 전체 구문은 https://docs.microsoft.com/en-us/sql/t-sql/language-elements/case-transact-sql을 참조하십시오.

declare @start time; 
declare @end time; 
select @start=cast('09:30:00.0000000' as time) 
select @end=cast('17:30:00.0000000' as time) 
SELECT Datename(dw,LastUpdate) as WeekDay 
    , FORMAT(PunchIn,'MM/dd/yyyy hh:mm tt') as PunchIn 
    , FORMAT(PunchOut,'MM/dd/yyyy hh:mm tt') as PunchOut 
    , Start = case 
     --employee punched in before 9:30 so take 9:30 as start time 
     when datediff(mi,@start,cast(PunchIn as time)) < 0 then @start 
     else cast(PunchIn as time) 
     end 
    , Stop = case 
     --employee punched out after 17:30 so take 17:30 as end time 
     when datediff(mi,@end,cast(PunchOut as time)) > 0 then @end 
     else cast(PunchOut as time) 
     end 
from TimeTracker 

참고 : 원본 코드에는 @start 변수에 대한 참조가 포함되어 있습니다. 허용되지 않습니다. "변수에 값을 할당하는 SELECT 문은 데이터 검색 작업과 결합되어서는 안됩니다."(실제 T-SQL 오류 메시지). 따라서 게시 된 솔루션에는 5 개의 열 (평일, PunchIn, PunchOut, 시작, 중지)로 구성된 결과 집합이 표시됩니다. 변수를 사용하고 두 개 이상의 레코드가 쿼리에서 반환 된 경우 마지막 레코드 만 이러한 변수에 저장됩니다! 전체 세트를 다른 테이블에 저장하려면 "FROM"키워드 앞에 추가 라인을 추가하십시오.

into [table name] 

+0

사려 깊은 대답에 감사드립니다. 모든 사람들로부터받은 모든 대답과 좋은 조언을 바탕으로 진행 방법을 잘 이해하고 있습니다. 내가 Stackoverflow를 처음 접했을 때 나는 대답을 받아 들일 수있는 대답으로 받아 들일 수 있을지 잘 모르겠다 -이 경우 나는 Z.M을 취할 것이다. Jarzebowski의 대답은 제 질문에 대한 포괄적 인 대답입니다. 비록 모든 다른 대답이 저의 최종 해결책에 도움이되었지만 말입니다. 모두에게 감사드립니다. –

0

CASE 문을 사용하여 특정 값 표시을 선택합니다. 명령문에 대한 특정 값 결과가 있어야합니다. CASE 문은 이 아니며if 조건부 ... 실행 코드로 평가되지 않습니다. 그래서 그 대신이의

는 :

--Bad 
CASE WHEN 1=0 THEN Select @[email protected] ELSE Select @[email protected] END 

이 같은 일을 할 수 있습니다

--Better 
SELECT @x = CASE WHEN 1=0 THEN [email protected] ELSE [email protected] END 

이것은 여전히 ​​표현에 일부 코드를 넣을 수 있습니다 보여줍니다,하지만 여전히 아래로 평가해야 값은입니다.여기에 질문에 대한

, 그것은 더 다음과 같아야합니다

case 
    --employee punched in before 9:30 so take 9:30 as start time 
    when datediff(mi,@start,cast(PunchIn as time))<0 then '09:30:00.0000000' 
    else PunchIn end 

난 아직 여기에 할당을하고 질문을하지만.

이 코드는 또한 내가 본 대부분의 관할권에서이 같은 PunchIn 시간을 변경하는 것은 매우 불법이므로 흥미 롭습니다. 직원이 징계 문제가 될 수 있다고 가정되기 전에 (경영진이 일찍 들어오지 말고 서면으로 작성하고 결국 해고하라고 요청할 것입니다.) 법이 정해지기 전까지는 그들이 일한 시간 동안 돈을 지불하십시오. 다시 말하지만, 이것은 관할 구역이므로 변호사와상의하십시오. 그러나 노동자들로부터 시간을 훔치는 것처럼 보입니다.

+0

고맙습니다. 매우 사려 깊고 교육적인 답변에 감사드립니다. 시간에 펀치를 변경하는 방법에 대한 요점이 잘 잡혀 있습니다. 해당 코드는 오전 9시 30 분에서 오후 5시 30 분 사이에 작업 한 실제 시간을 계산하는 데 사용됩니다. (임금) 계산을위한 것이 아니라 임의의 성과 인센티브를 계산하기위한 것입니다. 직원은 실제 펀치 인 및 펀치 아웃 시간에 따라 지급됩니다. 어쨌든 우리 HR 부서에서 귀하의 의견을 말하게 될 것입니다. 다시 한번 감사드립니다. –