Oracle SQL需要表中的下一行

时间:2017-01-20 10:09:12

标签: sql oracle

我在下面的代码中得到空白输出。我的代码是在按升序排列表后拉出下一个状态,即每当cargo_status_id = 32时,它应该拉下一个状态。请帮我解决这个或任何更好的选择。

对于Ex:

Shipment_id ---------状态---------- CHANGE_DATE --------------- Employee_id

----- 1234 --------------- 211 ---------- 1月17日下午12:32 -------- -------- 1111

----- 1234 --------------- 32 ----------- 1月17日01:32 PM ------- --------- 1111

----- 1234 --------------- 23 ----------- 1月17日02:32 PM ------- --------- 1111

所以在这个例子中,它应该将23和10月17日02: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

2 个答案:

答案 0 :(得分: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                              

N.B。如果您想过滤行以返回仅针对特定行的结果,则需要使用外部查询来执行此操作,因为分析函数适用于当前结果集,如果过早过滤,您将结束错误的结果。

答案 1 :(得分: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。您可以指定第三个参数来替换空输出。例如:LEAD(status,1,status),它给出了自己的最后一行状态,而不是null