从另一列计算的列?
假设表格如下:从另一列计算的列?
id | value
--------------
1 6
2 70
有没有一种方法来添加一个基于在同一个表的另一列自动计算列?像VIEW一样,但是是同一张桌子的一部分。作为示例,calculated
将是value
的一半。 Calculated
应该在value
更改时自动更新,就像VIEW一样。
其结果将是:
id | value | calculated
-----------------------
1 6 3
2 70 35
如果它是一个选择,你可以做到这一点是:
SELECT id, value, (value/2) AS calculated FROM mytable
否则,你也可以先改变表添加缺少的列和然后执行UPDATE查询以计算新列的值:
UPDATE mytable SET calculated = value/2;
如果它必须是自动的,并且哟你可以使用MySQL版本,你可以试试triggers
如果你想添加一列到自动更新到其他列的一半的表中,你可以用触发器来实现。
但我认为已经提出的答案是一个更好的方法来做到这一点。
干编码触发:
CREATE TRIGGER halfcolumn_insert AFTER INSERT ON table
FOR EACH ROW BEGIN
UPDATE table SET calculated = value/2 WHERE id = NEW.id;
END;
CREATE TRIGGER halfcolumn_update AFTER UPDATE ON table
FOR EACH ROW BEGIN
UPDATE table SET calculated = value/2 WHERE id = NEW.id;
END;
我不认为你只能让一个触发器,因为事件,我们必须响应是不同的。
谢谢。在这种情况下,我们还应该考虑删除? – 2016-07-06 07:03:53
@ krtek的回答是正确的方向,但有几个问题。
坏消息是在同一张表上的触发器中使用UPDATE将不起作用。好消息是没有必要。有一个新的对象,你甚至可以在桌子被触摸之前进行操作。
触发变为:
CREATE TRIGGER halfcolumn_update BEFORE UPDATE ON my_table
FOR EACH ROW BEGIN
SET NEW.calculated = NEW.value/2;
END;
还要注意BEGIN ... END;语法必须用不同的分隔符生效。整个shebang变成:
DELIMITER |
CREATE TRIGGER halfcolumn_insert BEFORE INSERT ON my_table
FOR EACH ROW BEGIN
SET NEW.calculated = NEW.value/2;
END;
|
CREATE TRIGGER halfcolumn_update BEFORE UPDATE ON my_table
FOR EACH ROW BEGIN
SET NEW.calculated = NEW.value/2;
END;
|
DELIMITER ;
注意:在上面的代码中,将单词“table”替换为您的表名称。我认为作者只是忘记了表名,并在“ON表”之后添加了它,并浪费了几分钟的时间。 – Bloodboiler 2015-12-23 09:31:05
良好的电话@Bloodboiler - 我修改了一小段更清晰的代码片段。 – Jerry 2016-01-14 18:52:54
MySQL 5.7支持计算列。他们称之为“生成的列”,语法有点奇怪,但它支持我在其他数据库中看到的相同选项。
https://dev.mysql.com/doc/refman/5.7/en/create-table.html#create-table-generated-columns
不幸的是,“生成列”不是ISO SQL标准的一部分。看起来像唯一的“ISO SQL”解决方案将是使用VIEW。 – PowerGamer 2015-07-19 08:59:29
生成列是MySQL版本,这是5.7.6及以上的良好的方法之一。
有两种生成列的:
- 虚拟(默认) - 列将在运行中计算时, 记录从表中读取
- 存储 - 列将被计算时, 在表中写入/更新新记录
两种类型都可以有NOT NULL限制,但只有存储的生成列可以是索引的一部分。
对于目前的情况,我们将使用存储的生成列。为了实现我都认为,无论是计算所需的值出现在表
CREATE TABLE order_details (price DOUBLE, quantity INT, amount DOUBLE AS (price * quantity));
INSERT INTO order_details (price, quantity) VALUES(100,1),(300,4),(60,8);
量会自动在表中弹出,你可以直接访问它,也请注意,每当您将更新任何列,金额也会得到更新。
我认为这应该是被接受的答案 – 2017-08-04 12:15:14
同意,这是正确的答案。 – 2017-11-16 00:19:55
根据文档,这只适用于NDB存储引擎,而不是InnoDB – cliffordheath 2017-11-30 05:19:09
我希望这仍然可以帮助很多人可能会看到这篇文章的人。如果您需要一个计算列,为什么不在视图中公开您想要的列?不要只保存数据或用触发器重载性能......只需在视图中公开已经格式化/计算出的数据即可。
希望这有助于...
那么,为什么不使用视图? – 2014-11-18 17:44:44
持久性(又名存储)计算列通常更便宜阅读,因为它们与其他列一样存储。他们甚至可以被索引。 – 2017-05-16 22:29:43
非永久计算列只是一个便利功能。在处理ORM时,它通常比视图更好。 – 2017-05-16 22:30:51