2010-05-26 2 views
0

다음은 레코드 반복을 통해 수행하려고하는 작업입니다.필드 합계를 기준으로 레코드를 업데이트 한 다음 합계를 사용하여 SQL에서 새 값 계산

SQL에서이 작업을 수행하는 최선의 방법이 아니므로 가능하면보다 우아한 솔루션을 갖고 싶습니다.

set @counter = 1 

declare @totalhrs dec(9,3), @lastemp char(7), @othrs dec(9,3) 

while @counter <= @maxrecs 
begin 
    if exists(select emp_num from #tt_trans where id = @counter) 
    begin 
    set @nhrs = 0 
    set @othrs = 0 

    select @empnum = emp_num, @nhrs = n_hrs, @othrs = ot_hrs 
    from #tt_trans 
    where id = @counter 

    if @empnum = @lastemp 
    begin 
     set @totalhrs = @totalhrs + @nhrs 

     if @totalhrs > 40 
     begin 
     set @othrs = @othrs + @totalhrs - 40 
     set @nhrs = @nhrs - (@totalhrs - 40) 
     set @totalhrs = 40 
     end 
    end 
    else 
    begin 
     set @totalhrs = @nhrs 
     set @lastemp = @empnum 
    end 

    update #tt_trans 
    set n_hrs = @nhrs, 
     ot_hrs = @othrs 
    where id = @counter and can_have_ot = 1 
    end 

    set @counter = @counter + 1 
end 

들으

+1

잠시만 기다려주십시오. 기존 코드에는 꽤 심각한 로직 문제가 있다고 생각합니다. 총 직원 수와 정규 근무 시간을 결정하여 각 직원의 모든 시간을 합산하는 것 같습니다. 그런 다음 각 직원에 대한 마지막 레코드의 n_hrs (덮어 쓰기) 및 ot_hrs 열을 업데이트합니다. 나는 ypu'd가 그것을하고 싶어하는 상황을 상상할 수 없다. 그래서 무언가는 잘못입니다. 당신이하려는 일을 영어로 설명 할 수 있습니까? 아마도 테이블의 내용에 대한 예제를 전후로 제공하고 있을까요? – JohnFx

+0

기본적으로 내가해야 할 일은 한 시간에 40 시간 이상을 지닌 모든 직원이 초과 근무를 한 사실을 감안하여 펀치를 조정하는 것입니다. 그것은 n_hrs를 철회하고 ot_hrs로 시간을 이동하여 총 시간을 동일하게 유지합니다. 최종 사용자는 ot_hrs (파산 일 때) (40 일)를 확인할 수 있어야합니다. – Casey

+0


전에 EMP # 1 n_hrs ot_hrs 날짜
1 0 8.2 1 8.5 1/1

0 1/2 1 0 8.6 1 8.7 1/3

0 1/4 1 0 8.0 1/5 10.3 2 0 (1/1)
2 10.6 0
1/2 2 1/3 12.0 0 10.0 0
2 1/4

EMP 번호 n_hrs ot_hrs 날짜 이후
1 0 8.2 1 8.5 1/1

0 1/2 1 0 8.6 1/3
1 8.7 0 1/4
1 6.0 2.0 1/5
2 10.3 0 1/1
2 10.6 0 1/2
2 12.0 0 1/3
2 7.1 2.9 1/4 – Casey

답변

0
update #tt_trans 
    set n_hrs = case 
    when t2.totHrs > 40 
    then n_hrs - (t2.totHrs -40) 
    else n_hrs 
    end, 
    ot_hrs = case 
    when t2.totHrs > 40 
    then ot_hrs + (t2.totHrs -40) 
    else ot_hrs 
    end 
    from #tt_trans t1 
    join (select sum (n_hrs) as totHrs, emp_num from #tt_trans where can_have_ot =1 group by emp_num) t2 on t1.emp_num = t2.emp_num where t1.post_date = (select max(post_date)from #tt_trans where emp_num = t1.emp_num) 

기본적으로 기간의 마지막 날짜의 수정 된 시간을 사용하여 수정했습니다. 두 분 모두에게 감사드립니다. 두 답장 모두 저를 이끌었습니다.

1

이 당신이 원하는에 가까운,하지만 당신은 당신이 정말로 달성하려고하는 일에 대해 내 의견을 대답하면 조금 조정해야합니다.

update #tt_trans 
    set n_hrs = CASE WHEN T2.totHrs>40 
        THEN 40 
        ELSE T2.totHrs END, 
    ot_hrs= CASE WHEN T2.totHrs>40 
       THEN T2.totHrs-40 
       ELSE 0 END 
FROM #tt_trans trans T1 
INNER JOIN (SELECT SUM(@nhrs) totHrs, EmpNum 
      FROM #tt_trans 
      WHERE can_have_ot=1 
      GROUP BY EmpNum) T2 ON (T1.EmpNum=T2.EmpNum) 

WHERE can_have_ot = 1 
0

여러 레코드에서 주어진 직원의 총 시간을 추적해야하므로 반복하는 것처럼 보입니다. 대신 내부 선택을 사용하여 각 직원의 시간을 합산하고 #tt_trans 테이블에 선택 항목을 참여시킬 수 있습니다. 해당 조인에서 갱신 사항을 작성하고 갱신 컬럼에 대한 CASE 문에 논리를 입력하십시오.

관련 문제