【问题标题】:How to get the last row of an Oracle a table如何获取Oracle表的最后一行
【发布时间】:2012-09-04 21:32:50
【问题描述】:

我想获取最后一行,我将其插入到 Oracle 11g Express 数据库的表中。 我该怎么做?

【问题讨论】:

  • SELECT * FROM t WHERE id = (SELECT MAX(id) FROM t)
  • 只有当 OP 的表的 id 为 pk 并且是递增列时才有效。试试“select * from table where rowid in (select max(rowid) from table)”
  • @MichaelN,rowids 不保证以任何顺序插入。
  • @ALL - 我有一个带有序列和触发器的 PK 以自动生成行 ID。
  • 本,感谢您的更正。我写的时候就知道这听起来不对。

标签: sql oracle oracle11g


【解决方案1】:

表中没有“最后”行,因为 Oracle 表没有顺序的概念。

但是,假设您想找到最后插入的主键并且这个主键是一个递增的数字,您可以执行以下操作:

select *
  from ( select a.*, max(pk) over () as max_pk
           from my_table a
                )
 where pk = max_pk

如果您知道每行的创建日期,如果列名为 created,则该日期将变为:

select *
  from ( select a.*, max(created) over () as max_created
           from my_table a
                )
 where created = max_created

或者,您可以使用聚合查询,例如:

select *
  from my_table
 where pk = ( select max(pk) from my_table )

这里有一个小SQL Fiddle 来演示。

【讨论】:

  • 在大约 30 亿行的表上尝试(中间查询)时出现此错误 ORA-01652:无法在表空间 TEMP 01652 中将临时段扩展 128。00000 -“无法扩展表空间 %s 中 %s 的临时段” *原因:未能为指示的表空间中的临时段分配所需块数的范围。 *操作:使用 ALTER TABLESPACE ADD DATAFILE 语句将一个或多个文件添加到指定的表空间。
  • 你有一个 30 亿行的表,你想找到最后一行 @Sambit?我可以向您保证,您不需要找到最后一行。首先重新评估需求。如果您确实确实需要找到最后一行,则需要一种唯一标识它的方法,或者您需要增加排序空间的数量(这是导致错误的原因)
  • 你说得对,我尝试了一个有 10 亿行的表,它成功了!不幸的是,我想找到最后添加的行的 rowid,我无法找出最后一个时间戳。但是,我稍微修改了您的查询并且它起作用了。而不是“select a.*, max(created)...” 我使用“select a.rowid, max(created)..) 它适用于 3 B 表。
  • 我假设您没有将MY_ID 存储在具有数字数据类型@vapcguy 的列中,字符串的二进制排序可以解释您所看到的行为。如果不是,最好用 [mvce] 提出一个新问题。如果你这样做,请联系我,我很想看看问题是什么。在 rowids 上,如果您只将直接路径插入到未分区的堆表中,您永远不会以任何方式更改(包括标准管理员),并且您只有一个具有可用空间的数据文件并且从不执​​行任何其他操作,那么它就是可能 rowids 将处于“升序”...
  • 使用currval 也可以使用require you to be in the same session as the last use of nextval @Superdooperhero。如果有多个会话写入表或某个值被丢弃的可能性,即由于语句失败,最好使用数据驱动的方法。
【解决方案2】:
SELECT * FROM (
    SELECT * FROM table_name ORDER BY sortable_column DESC
) WHERE ROWNUM = 1;

【讨论】:

  • 这真的有效吗?我认为rownum 之前应用了order by 子句,这意味着它会忽略你在那里进行的排序。 oracle.com/technetwork/issue-archive/2006/06-sep/…
  • @AlexMoore-Niemi 括号中的排序首先发生,因此 rownum 在此示例中有效。您将在链接的文章中进一步看到这一点。尝试对其进行测试,您应该会看到它有效。
  • 我试过这个,但得到了错误的 ID。我有一个使用insert into /*+ append */ 和ORDER BY DESC 在主键ID 列上从另一个构建的表。当我最初构建表格时,它以 1-75 的正确顺序排列行。当我运行此查询或执行select * from ( select a.*, max(pk) over () as max_pk from my_table a ) where pk = max_pk 时,我得到9。如果我做SELECT ID FROM MyTable WHERE ROWID IN (SELECT MAX(ROWID) FROM MyTable),我会得到75的正确ID。
  • @vapcguy 您在发布的查询中没有 ROWNUM。也许你评论错了例子。
  • @vapcguy 告诉我 9 是正确的。您的 ID 可能是字符串而不是数字。
【解决方案3】:
select * from table_name ORDER BY primary_id DESC FETCH FIRST 1 ROWS ONLY;

这是最简单的,不做子查询

【讨论】:

  • 这只适用于Oracle 12+版本,不适用于Oracle 11g
  • 最简单的......而且可能是最快的
【解决方案4】:

最后一行按照复合键 K(k1, ..., kn) 的严格全序排列:

SELECT  *
FROM    TableX AS o
WHERE   NOT EXISTS (
            SELECT  *
            FROM    TableX AS i
            WHERE   i.k1 > o.k1
                OR  (i.k1 = o.k1 AND i.k2 > o.k2)
                ...
                OR  (i.k1 = o.k1 AND i.k2 = o.k2 AND i.k3 = o.k3 AND ... AND i.kn > o.kn)
        )
;

考虑到 K 很简单(即非复合)的特殊情况,上面的缩写为:

SELECT  *
FROM    TableX AS o
WHERE   NOT EXISTS (
            SELECT  *
            FROM    TableX AS i
            WHERE   i.k1 > o.k1
        )
;

请注意,要使此查询仅返回一行,键必须无关系排序。如果允许关联,则此查询将返回与最大键关联的所有行。

【讨论】:

  • 不知道,这是正确的。不过,您使用的语言非常密集。不要失去准确性,但理解您答案的人越多越好。
【解决方案5】:

你可以这样做:

SELECT * FROM (SELECT your_table.your_field, versions_starttime
               FROM your_table
               VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE)
WHERE ROWNUM = 1;

或者:

SELECT your_field,ora_rowscn,scn_to_timestamp(ora_rowscn) from your_table WHERE ROWNUM = 1;

【讨论】:

  • 内部选择不保证顺序,除非你指定它......第一行可以是任何东西。
【解决方案6】:
SELECT * FROM 
  MY_TABLE
WHERE 
  <your filters>
ORDER BY PRIMARY_KEY DESC FETCH FIRST ROW ONLY

【讨论】:

    【解决方案7】:
    $sql = "INSERT INTO table_name( field1, field2 )  VALUES ('foo','bar') 
            RETURNING ID INTO :mylastid";
    $stmt = oci_parse($db, $sql);
    oci_bind_by_name($stmt, "mylastid", $last_id, 8, SQLT_INT);
    oci_execute($stmt);
    
    echo "last inserted id is:".$last_id;
    

    提示:您必须在下面的 {your_id_col_name} 中使用您的 id 列名...

    "RETURNING {your_id_col_name} INTO :mylastid"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-28
      • 1970-01-01
      • 2016-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多