2017-01-20 3 views
0

下のコードで空白の出力が表示されています。私のコードは、テーブルを昇順に配置した後、すなわち、shipment_status_id = 32になるたびに次のステータスを取得する必要があります。これ以上の代替案を修正するのを手伝ってください。例についてはテーブル内の次の行にOracle SQLが必要

Shipment_id ---------ステータス---------- CHANGE_DATE --------------- EMPLOYEE_ID

----- 1234 --------------- 211 ---------- 10 Jan 17 12:32 PM -------- -------- 1111

----- 1234 --------------- 32 ----------- 10 Jan 17 01 :32 PM ---------------- 1111

----- 1234 --------------- 23 ---- ------- 10 Jan 17 02:32 PM ---------------- 1111

ので例では、それが出力として23、10 1月17日に午前2時32分PMを与える必要があります

おかげで、

SELECT DISTINCT A41.shipment_id 
    ,A41.shipment_status_id 
    ,A41.CHANGE_DATE 
FROM (
    SELECT DISTINCT shipment_id 
     ,holder_employee_id 
     ,shipment_status_id 
     ,CHANGE_DATE 
     ,row_number() OVER (
      PARTITION BY shipment_id ORDER BY CHANGE_DATE ASC 
      ) AS rn1 
    FROM db1.table1 
    WHERE TRUNC(CHANGE_DATE) = to_date('{RUN_DATE_YYYY-MM-DD}', 'YYYY-MM-DD') 
    ) A41 
WHERE rn1 = CASE 
     WHEN shipment_status_id IN (32) 
      AND rn1 = 1 
      THEN 2 
     WHEN shipment_status_id IN (32) 
      AND rn1 = 2 
      THEN 3 
     WHEN shipment_status_id IN (32) 
      AND rn1 = 3 
      THEN 4 
     WHEN shipment_status_id IN (32) 
      AND rn1 = 4 
      THEN 5 
     WHEN shipment_status_id IN (32) 
      AND rn1 = 5 
      THEN 6 
     WHEN shipment_status_id IN (32) 
      AND rn1 = 6 
      THEN 7 
     WHEN shipment_status_id IN (32) 
      AND rn1 = 7 
      THEN 8 
     WHEN shipment_status_id IN (32) 
      AND rn1 = 8 
      THEN 9 
     WHEN shipment_status_id IN (32) 
      AND rn1 = 9 
      THEN 10 
     END 
+1

質問を更新してください。いくつかのサンプルデータとクエリの予想される出力を追加してください。おそらく、あなたは 'LEAD()'解析関数の後にいるでしょうか? 'table1_v1.rn1 = table1_v2.rn1 + 1'のself-join – Boneist

+0

WHERE句のCASE式の代わりにAND/ORを使う方が良いでしょう。 – jarlh

+0

また、where句は、 'rn1 = rn1 + 1'の行のサブセットが必要だと効果的に言っています。 (つまり1 = 2)返された行がなくなってしまう理由です。 – Boneist

答えて

2

LEAD()のように見えるあなたは後にしている正確に何である:

WITH table1 AS (SELECT 1234 shipment_id, 211 status, to_date('10/01/2017 12:32', 'dd/mm/yyyy hh24:mi') change_date, 1111 employee_id FROM dual UNION ALL 
       SELECT 1234 shipment_id, 32 status, to_date('10/01/2017 12:32', 'dd/mm/yyyy hh24:mi') change_date, 1111 employee_id FROM dual UNION ALL 
       SELECT 1234 shipment_id, 23 status, to_date('10/01/2017 12:32', 'dd/mm/yyyy hh24:mi') change_date, 1111 employee_id FROM dual) 
-- end of mimicking a table called table1 with data in it. See SQL below: 
SELECT shipment_id, 
     status, 
     change_date, 
     employee_id, 
     LEAD(status) OVER (PARTITION BY shipment_id ORDER BY change_date) next_status, 
     LEAD(change_date) OVER (PARTITION BY shipment_id ORDER BY change_date) next_change_date, 
     LEAD(employee_id) OVER (PARTITION BY shipment_id ORDER BY change_date) next_employee_id 
FROM table1; 

SHIPMENT_ID  STATUS CHANGE_DATE EMPLOYEE_ID NEXT_STATUS NEXT_CHANGE_DATE NEXT_EMPLOYEE_ID 
----------- ---------- ----------- ----------- ----------- ---------------- ---------------- 
     1234  211 10/01/2017   1111   23 10/01/2017 12:32    1111 
     1234   23 10/01/2017   1111   32 10/01/2017 12:32    1111 
     1234   32 10/01/2017   1111        

NB特定の行だけの結果を返すように行をフィルタリングする場合は、解析関数が現在の結果セットを処理するため、外部クエリを使用する必要があります。早すぎるフィルタリングを行うと終了します間違った結果が出る。

+0

ありがとうございましたBoneist、 以前のステータスも教えてください。 –

+0

LAG()は直前の行を見る関数になります。 – Boneist

1

このケースではLEAD()関数を使用できます。

Select shipment_id, 
     status 
     lead(status,1) over(partition by shipment_id order by change_date) next_status, 
     change_date, 
     lead(change_date,1) over (partition by shipment_id order by change_date) next_change_date 
from table 1 
where shipment_id='1234' 
order by change_date; 

注:最後の行の 'LEAD()の関数出力はnullになります。第3引数を指定すると、ヌル出力を置き換えることができます。例:LEAD(status,1,status)最終行のステータスが自己の代わりにnull

+0

質問を再読みすると、 'status 'として誤って' shipment_id'が読み込まれます(32の値はステータス値ですが、OPの例のshipment_idは1234です)だから、おそらくそれはあなたのクエリのshipment_id値の入力ミスですか? – Boneist

+0

同じことを通知してくれてありがとう、その修正されました。 –

関連する問題