4

Hi I have an interesting problem. I Have an Employee Table AS Follows

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

Now the tables have employees some of whom get paid monthly,some weekly, some biweekly and some daily. What we want is to find an Indicator saying 'Y' if the salary of three consecutive Pay Periods is equal. Lets take the following example.

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

In this case the indicator should be Yes because 3 consecutive pay periods have a salary of $200.

Since the number of pay periods is not constant I am unsure of how to write this code because I do not know from before hand how many left joins I will need.Since I am writing this in Teradata I tried using the RECURSIVE Function but got stumped. Any general ideas on how to proceed with this?I would prefer not creating a stored procedure or having PL/SQL logic.

4

2 回答 2

12

Teradata 可能不像 Oracle 和 SQL Server 现在支持的方式支持 LEAD 和 LAG,但这些功能的前提是为您的窗口聚合函数选择正确的窗口。在 Teradata 中,可以通过在窗口聚合函数中使用 ROWS BETWEEN 子句来完成 LEAD 和 LAG。

以下是您如何使用 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;

结果

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
于 2012-10-28T15:57:01.587 回答
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. 其次,您的支付期应该有两个日期,开始日期和结束日期。

于 2012-10-27T00:03:23.413 回答