2012-10-26 3 views
3

안녕하세요 저는 흥미로운 문제가 있습니다. 나는 이제 테이블이 일부 격주 일부 매일 그들 중 일부는 일부 매주, 매월 지불 직원을 가지고 직원 테이블로가3 테이블의 연속적인 행

CREATE TABLE EMPLOYEE(
EMPLOYEE_ID INTEGER, 
SALARY DECIMAL(18,2), 
PAY_PERIOD DATE) 

을 따릅니다 되세요. 우리가 원하는 것은 3 개의 연속 지불 기간의 급여가 동일하면 'Y'를 나타내는 지표를 찾는 것입니다. 다음 예제를 보겠습니다.

Employee Pay_Period  Salary 

    1   01/01/2012 $500 
    1   08/01/2012 $200 
    1   15/01/2012 $200 
    1   22/01/2012 $200 
    1   29/01/2012 $700 

이 경우 3 개의 연속 급여 기간에 급여가 $ 200이기 때문에 표시기가 예이어야합니다.

지불 기간의 수가 일정하지 않으므로이 코드를 작성하는 방법을 알지 못하기 때문에 필요한만큼 왼쪽 조인을 손에서 미리 알 수 없으므로이 코드를 작성합니다. 이후 Teradata에서 쓰고 있기 때문에 RECURSIVE 기능이 떨어졌지만. 이 진행 방법에 대한 일반적인 아이디어는? 저장 프로 시저를 만들지 않거나 PL/SQL 로직을 만들지 않는 것이 좋습니다.

+1

을 : 여기

당신이 사이 테이블에 단일 패스 행을 사용하여이 작업을 수행하기 위해 무엇을 찾고있는 달성 할 수있는 방법입니다 오라클의 – Randy

+0

기능을 사용하면 전혀 비용을 지불하지 않을 것입니다. 이것은 Larry() 함수입니다. – wildplasser

답변

11

Teradata는 Oracle 및 SQL Server에서 지원하는 방식으로 LEAD 및 LAG를 지원하지 않을 수 있지만 이러한 기능의 전제는 Window Aggregate 기능에 맞는 올바른 창을 선택하는 데 기반합니다. Teradata에서 LEAD 및 LAG는 Window Aggregate Function에서 ROWS BETWEEN 절을 사용하여 수행 할 수 있습니다.

CREATE VOLATILE TABLE myTable 
(myID SMALLINT NOT NULL, 
    PayPeriod DATE NOT NULL, 
    PayAmount DECIMAL(5,2) NOT NULL) 
PRIMARY INDEX (myID) 
ON COMMIT PRESERVE ROWS; 

INSERT INTO myTable VALUES (1, DATE '2012-01-01', 500); 
INSERT INTO myTable VALUES (1, DATE '2012-01-08', 200); 
INSERT INTO myTable VALUES (1, DATE '2012-01-15', 200); 
INSERT INTO myTable VALUES (1, DATE '2012-01-22', 200); 
INSERT INTO myTable VALUES (1, DATE '2012-01-29', 700); 


SELECT myID 
    , PayPeriod 
    , PayAmount 
    , MAX(PayAmount) OVER (PARTITION BY myID 
           ORDER BY PayPeriod 
          ROWS BETWEEN 1 FOLLOWING 
            AND 1 FOLLOWING) AS NextPayAmount_ 
    , MAX(PayAmount) OVER (PARTITION BY myID 
           ORDER BY PayPeriod 
          ROWS BETWEEN 2 FOLLOWING 
            AND 2 FOLLOWING) AS NextPayAmount2_ 
    , CASE WHEN NextPayAmount_ = PayAmount 
      AND NextPayAmount2_ = PayAmount 
      THEN 'Y' 
      ELSE 'N' 
     END PayIndicator_ 
    FROM myTable; 

결과 이것은 LAG 것 오라클에

1 2012-01-01 500 200 200 N 
1 2012-01-08 200 200 200 Y 
1 2012-01-15 200 200 700 N 
1 2012-01-22 200 700 ? N 
1 2012-01-29 700 ? ? N 
+1

나는이 솔루션을 좋아한다. 이것에 대해 고마워. 이것은 매우 유용했습니다! – Eosphorus

2

Teradata에는 리드/래그가 없습니다. 그러나 row_number()이 있습니다. 따라서 원하는대로 할 수 있습니다.

with as (
    select e.*, 
      row_number() over (partition by employee_id order by pay_period) as seqnum 
    from employee 
) 
select <whatever you want> 
from emp e join 
    emp e1 join 
    on e.employee_id = e1.employee_id and 
     e.seqnum = e1.seqnum+1 
    emp e2 
    on e.employee_id = e2.employee_id and 
     e.seqnum = e2.seqnum+2 
where e.salary = e1.salary and e.salary = e2.salary 

나는이 밖에도 몇 가지 제안을하고 있습니다. 먼저 employee 테이블에는 직원 당 행이 하나 있어야하며 기본 키는 employee_id입니다. 이 표는 EmployeeSalary과 같은 형식이어야합니다. 둘째, 지불 기간에는 시작 날짜와 종료 날짜의 두 가지 날짜가 있어야합니다.