【问题标题】:How to write a Mysql Generated Column that returns true if it is the most recent entry?如果它是最新条目,如何编写返回 true 的 Mysql 生成列?
【发布时间】:2022-07-19 23:36:51
【问题描述】:

我的Mysql表目前是这样的:

id time
1 2011-12-12 09:27:24
1 2011-12-13 09:27:31
1 2011-12-14 09:27:34
2 2011-12-14 09:28:21

我想添加一个返回布尔值的虚拟生成列。如果它是给定 id 的最新条目,则该布尔值将为真。

id time is_last_entry
1 2011-12-12 09:27:24 0
1 2011-12-13 09:27:31 0
1 2011-12-14 09:27:34 1
2 2011-12-14 09:28:21 1

我应该如何写这个声明?

CREATE TABLE test(
    id INT NOT NULL,
    time DATETIME NOT NULL,
    is_last_entry TINYINT GENERATED ALWAYS AS [=> please complete here]
);

【问题讨论】:

  • 我认为您正在寻找触发器而不是 GENERATED ALWAYS AS

标签: mysql sql


【解决方案1】:

生成的列只能有一个引用同一行中的列的表达式,因此无法确定该行是否在所有其他行中具有最大的时间值。生成的列也不能使用子查询或窗口函数或任何其他可以比较其他行中的值的方法。

上面的一条评论建议使用触发器,但这在 MySQL 中不起作用,因为您无法针对生成触发器的同一个表进行更新。

例子:

mysql> create trigger t before insert on test for each row 
  update test set is_last_entry = 0 where time < NEW.time;

mysql> insert into test (id time) values (1, now());
ERROR 1442 (HY000): Can't update table 'test' in stored function/trigger 
  because it is already used by statement which invoked this stored function/trigger.

你有两个选择:

  1. 在此表中插入/更新/删除行后,您必须显式执行其他更新以在最新行上设置布尔列。

  2. 根本不存储布尔值的列,而是在查询时使用窗口函数,这样查询的结果总是保证是最新的:

    mysql> select id, time, time = max(time) over() as is_last_entry from test;
    +----+---------------------+---------------+
    | id | time                | is_last_entry |
    +----+---------------------+---------------+
    |  1 | 2022-07-19 08:32:32 |             1 |
    |  2 | 2020-06-06 00:00:00 |             0 |
    +----+---------------------+---------------+
    

【讨论】:

    猜你喜欢
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多