4

こんにちは私は興味深い問題を抱えています。私は次のように従業員テーブルを持っています

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ロジックを使用したりしたくないです。

4

2 に答える 2

12

Teradataは、OracleおよびSQL Serverが現在サポートしている方法でLEADおよびLAGをサポートしない場合がありますが、これらの関数の前提は、WindowAggregate関数の正しいウィンドウの選択に基づいています。Teradataでは、LEADおよびLAGは、WindowAggregate関数でROWSBETWEEN句を使用して実行できます。

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テーブルには、主キーが。の従業員ごとに1つの行が必要ですemployee_id。このテーブルは、のような名前にする必要がありますEmployeeSalary。次に、支払い期間には、開始日と終了日の2つの日付が必要です。

于 2012-10-27T00:03:23.413 に答える