获取Postgres中表格的最后记录

Luc*_*Luc 38 sql postgresql

我正在使用Postgres,无法获得我的表的最后一条记录:

 my_query = client.query("SELECT timestamp,value,card from my_table");
Run Code Online (Sandbox Code Playgroud)

如何知道时间戳是记录的唯一标识符?

bpg*_*rgo 75

如果在"最后一条记录"下,则表示具有最新时间戳值的记录,请尝试以下操作:

my_query = client.query("
  SELECT TIMESTAMP,
    value,
    card
  FROM my_table
  ORDER BY TIMESTAMP DESC
  LIMIT 1
");
Run Code Online (Sandbox Code Playgroud)

  • @WebWanderer`SELECT id,value,card FROM my_table ORDER BY id DESC LIMIT 1;` (7认同)
  • 如果您没有描述插入时间的时间戳列,该怎么办? (3认同)
  • 关键是使用 order by desc 和 limit 1 之后......就像上面的示例查询所示 (2认同)

chl*_*chl 15

您可以使用

SELECT timestamp, value, card 
FROM my_table 
ORDER BY timestamp DESC 
LIMIT 1
Run Code Online (Sandbox Code Playgroud)

假设你也想排序timestamp


Fab*_*cke 11

简单方法:ORDER BY 与 LIMIT 结合使用

SELECT timestamp, value, card
FROM my_table
ORDER BY timestamp DESC
LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

但是, LIMIT 不是标准的,正如Wikipedia 所述SQL 标准的核心功能没有明确定义 Null 的默认排序顺序。. 最后,当多条记录共享最大时间戳时,只返回一行。

关系方式:

这样做的典型方法是检查没有任何行的时间戳比我们检索的任何行都高。

SELECT timestamp, value, card
FROM my_table t1
WHERE NOT EXISTS (
  SELECT *
  FROM my_table t2
  WHERE t2.timestamp > t1.timestamp
);
Run Code Online (Sandbox Code Playgroud)

这是我最喜欢的解决方案,也是我倾向于使用的解决方案。缺点是当我们瞥见这个查询时,我们的意图不是很清楚。

指导方式:MAX

为了规避这一点,可以在子查询中使用 MAX 而不是相关性。

SELECT timestamp, value, card
FROM my_table
WHERE timestamp = (
  SELECT MAX(timestamp)
  FROM my_table
);
Run Code Online (Sandbox Code Playgroud)

但是如果没有索引,则需要对数据进行两次传递,而前一个查询只需扫描一次即可找到解决方案。也就是说,除非必要,否则我们在设计查询时不应考虑性能,因为我们可以期望优化器会随着时间的推移而改进。然而,这种特殊类型的查询非常常用。

炫耀方式:加窗函数

我不建议这样做,但也许你可以给你的老板或其他人留下好印象;-)

SELECT DISTINCT
  first_value(timestamp) OVER w,
  first_value(value) OVER w,
  first_value(card) OVER w
FROM my_table
WINDOW w AS (ORDER BY timestamp DESC);
Run Code Online (Sandbox Code Playgroud)

实际上,这表明一个简单的查询可以用多种方式表达(我可以想到其他几种方式),并且应该根据几个标准来选择一种或另一种形式,例如:

  • 可移植性(关系/指导性方式)
  • 效率(关系方式)
  • 表现力(简单/指导性方式)


小智 10

如果你的表没有整数自增等Id,也没有时间戳,你仍然可以通过以下查询获取表的最后一行。

select * from <tablename> offset ((select count(*) from <tablename>)-1)
Run Code Online (Sandbox Code Playgroud)

例如,这可以让您搜索更新的平面文件,查找/确认先前版本的结束位置,并将剩余行复制到表中。


小智 7

如果您接受提示,请在此表中创建一个id,如serial.该字段的默认值为:

nextval('table_name_field_seq'::regclass).
Run Code Online (Sandbox Code Playgroud)

因此,您使用查询来调用最后一个寄存器.使用你的例子:

pg_query($connection, "SELECT currval('table_name_field_seq') AS id;
Run Code Online (Sandbox Code Playgroud)

我希望这个提示可以帮到你.

  • _返回当前会话中此序列的 nextval 最近获得的值。_ 因此,如果当前会话中未调用“nextval”,这不仅会返回错误,而且您也不会看到其他会话中所做的更改会议。 (2认同)

Vig*_*aja 6

为了获得最后一行,

获取排序顺序中的最后一行:如果表有一列指定时间/主键,

  1. 使用LIMIT子句

SELECT * FROM USERS ORDER BY CREATED_TIME DESC LIMIT 1;

  1. 使用FETCH子句 -参考

SELECT * FROM USERS ORDER BY CREATED_TIME FETCH FIRST ROW ONLY;

获取行插入顺序中的最后一行:如果表没有指定时间/任何唯一标识符的列

  1. 使用CTID系统列,其中ctid表示表中行的物理位置 -参考

    SELECT * FROM USERS WHERE CTID = (SELECT MAX(CTID) FROM USERS);

考虑下表,

userid |username |    createdtime |
     1 |       A |  1535012279455 |
     2 |       B |  1535042279423 | //as per created time, this is the last row
     3 |       C |  1535012279443 |
     4 |       D |  1535012212311 |
     5 |       E |  1535012254634 | //as per insertion order, this is the last row
Run Code Online (Sandbox Code Playgroud)

查询 1 和 2 返回,

userid |username |    createdtime |
     2 |       B |  1535042279423 |
Run Code Online (Sandbox Code Playgroud)

当 3 个返回时,

userid |username |    createdtime |
     5 |       E |  1535012254634 |
Run Code Online (Sandbox Code Playgroud)

注意:更新旧行时,它会删除旧行并更新数据并作为新行插入表中。因此,使用以下查询将返回最晚进行数据修改的元组。

现在更新一行,使用

UPDATE USERS SET USERNAME = 'Z' WHERE USERID='3'

该表变为,

userid |username |    createdtime |
     1 |       A |  1535012279455 |
     2 |       B |  1535042279423 |
     4 |       D |  1535012212311 |
     5 |       E |  1535012254634 |
     3 |       Z |  1535012279443 |
Run Code Online (Sandbox Code Playgroud)

现在查询 3 返回,

userid |username |    createdtime |
     3 |       Z |  1535012279443 |
Run Code Online (Sandbox Code Playgroud)


All*_*tos 5

假设您以“ id”作为主键,则可以使用此查询最后插入的记录:

SELECT timestamp,value,card FROM my_table WHERE id=(select max(id) from my_table)
Run Code Online (Sandbox Code Playgroud)

假设插入的每个新行将使用表ID的最高整数值。