SQL call Max row number from a temp table

前端 未结 1 1202
遥遥无期
遥遥无期 2021-01-26 17:07

In the temp table there are only two columns available. I would like to get the most recent ID for each load, as shown in the picture below.

I have tried this but it doe

相关标签:
1条回答
  • 2021-01-26 17:41

    TEMP_TABLE lacks a sequential primary key or any other indicator for order of insertion. So it is not possible to get the latest ID for a LOAD using the columns of the table itself.

    However, there is one option: ORA_ROWSCN(). This is a pseudo-column which identifies the System Change Number for the transaction which changed the table. So we can reconstruct the order of insertion by sorting the table on ORA_ROWSCN.

    There are some caveats:

    1. By default the SCN applies to the block level. Consequently all the rows in a block have the same SCN. It's a good enough approximation for wide tables but hopeless for a two-column toy like TEMP_TABLE. We can track SCN at the row level but only if the table is created with ROWDEPENDENCIES. The default is NOROWDEPENDENCIES. Unfortunately, we cannot use ALTER TABLE here. You will need to drop and recreate the table (*) to enable ROWDEPENDENCIES.
    2. The SCN applies to the transaction. This means the solution will only work if each row in TEMP_TABLE is inserted in a separate transaction.
    3. Obviously this is only possible if TEMP_TABLE is an actual table and not a view or some other construct.

    Given all these criteria are satisfied here is a query which will give you the result set you want:

    select load, id
    from ( select load
                  , id
                  , row_number() over (partition by load order by ora_rowscn desc) as rn
           from temp_table
    )
    where rn = 1
    

    There is a demo on db<>fiddle. Also, the same demo except TEMP_TABLE defined with NOROWDEPENDENCIES, which produces the wrong result.


    (*) If you need to keep the data in TEMP_TABLE the steps are:

    1. rename TEMP_TABLE to whatever;
    2. create table TEMP_TABLE as select * from whatever rowdependencies;
    3. drop table whatever;

    However, the SCN will be the same for the existing rows. If that matters you'll have to insert each row one at a time, in the order you wish to preserve, and commit after each insert.

    0 讨论(0)
提交回复
热议问题