获取Postgres中表格的最后记录

时间:2011-06-07 15:44:35

标签: sql postgresql

我正在使用Postgres而无法获得我桌子的最后一条记录:

 my_query = client.query("SELECT timestamp,value,card from my_table");

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

11 个答案:

答案 0 :(得分:66)

如果在“last record”下,则表示具有最新时间戳值的记录,请尝试以下操作:

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

答案 1 :(得分:14)

你可以使用

SELECT timestamp, value, card 
FROM my_table 
ORDER BY timestamp DESC 
LIMIT 1

假设您还希望按timestamp排序?

答案 2 :(得分:6)

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

nextval('table_name_field_seq'::regclass).

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

pg_query($connection, "SELECT currval('table_name_field_seq') AS id;

我希望这个技巧可以帮到你。

答案 3 :(得分:5)

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

SELECT timestamp,value,card FROM my_table WHERE id=(select max(id) from my_table)

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

答案 4 :(得分:2)

便捷方式:将LIMIT与ORDER BY结合使用

SELECT timestamp, value, card
FROM my_table
ORDER BY timestamp DESC
LIMIT 1;

但是,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
);

这是我最喜欢的解决方案,也是我倾向于使用的解决方案。缺点是,一看这个查询,我们的意图就不会立即清楚。

教学方式:MAX

为避免这种情况,可以在子查询中使用MAX代替相关性。

SELECT timestamp, value, card
FROM my_table
WHERE timestamp = (
  SELECT MAX(timestamp)
  FROM my_table
);

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

炫耀方式:开窗功能

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

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);

实际上,这具有显示简单查询可以以多种方式表达的优点(我可以想到的其他几种方式),并且应根据多种条件来选择一种或另一种形式,例如为:

  • 可移植性(关系/指导方式)
  • 效率(关系方式)
  • 表现力(轻松/有指导性的方式)

答案 5 :(得分:0)

使用以下

SELECT timestamp, value, card 
FROM my_table 
ORDER BY timestamp DESC 
LIMIT 1

答案 6 :(得分:0)

如果您的表没有ID(例如整数自动递增),也没有时间戳,您仍然可以使用以下查询获取表的最后一行。

select * from <tablename> offset ((select count(*) from <tablename>)-1)

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

答案 7 :(得分:0)

这些都是很好的答案,但是如果您希望聚合函数执行此操作以捕获由任意查询there's a standard way to do this(取自Postgres Wiki,但应在任何情况下生成的结果集的最后一行)合理地符合十年或更早以前的SQL标准):

-- Create a function that always returns the last non-NULL item
CREATE OR REPLACE FUNCTION public.last_agg ( anyelement, anyelement )
RETURNS anyelement LANGUAGE SQL IMMUTABLE STRICT AS $$
        SELECT $2;
$$;

-- And then wrap an aggregate around it
CREATE AGGREGATE public.LAST (
        sfunc    = public.last_agg,
        basetype = anyelement,
        stype    = anyelement
);

如果顺序合理,通常更可取select ... limit 1,但是如果您需要在汇总中执行此操作并且希望避免使用子查询,这将非常有用。

有关自然答案,请参见this question

答案 8 :(得分:0)

列名按降序起着重要作用:

select <COLUMN_NAME1, COLUMN_NAME2> from >TABLENAME> ORDER BY <COLUMN_NAME THAT MENTIONS TIME> DESC LIMIT 1;

例如:下面提到的表(user_details)由具有表时间戳的列名“ created_at”组成。

SELECT userid, username FROM user_details ORDER BY created_at DESC LIMIT 1;

答案 9 :(得分:0)

在Oracle SQL中,

select * from (select row_number() over (order by rowid desc) rn, emp.* from emp) where rn=1;

答案 10 :(得分:-1)

要获取最后一行,

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

  1. 使用LIMIT子句

SELECT * FROM USERS ORDER BY CREATED_TIME DESC LIMIT 1;

  1. 使用FETCH子句-Reference

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

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

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

    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

查询1和2返回,

userid |username |    createdtime |
     2 |       B |  1535042279423 |

当3返回时,

userid |username |    createdtime |
     5 |       E |  1535012254634 |

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

现在使用

更新行

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 |

现在查询3返回,

userid |username |    createdtime |
     3 |       Z |  1535012279443 |