鉴于下表:
id | value
--------------
1 6
2 70
有没有办法添加一个根据同一个表中的另一列自动计算的列?像VIEW,但同一个表的一部分。例如,calculated
将是value
的一半。 Calculated
更改后value
会自动更新,就像VIEW一样。
结果将是:
id | value | calculated
-----------------------
1 6 3
2 70 35
答案 0 :(得分:47)
Generated Column是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);
金额将自动弹出表格,您可以直接访问,也请注意,每当您更新任何列时,金额也会更新。
答案 1 :(得分:31)
如果是选择,您可以这样做:
SELECT id, value, (value/2) AS calculated FROM mytable
否则,您还可以先更改表以添加缺少的列,然后执行UPDATE查询以计算新列的值:
UPDATE mytable SET calculated = value/2;
如果必须是自动的,并且您的MySQL版本允许,您可以尝试使用triggers
答案 2 :(得分:24)
MySQL 5.7支持计算列。他们称之为“Generated Columns”,语法有点奇怪,但它支持我在其他数据库中看到的相同选项。
https://dev.mysql.com/doc/refman/5.7/en/create-table.html#create-table-generated-columns
答案 3 :(得分:21)
@ 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 ;
答案 4 :(得分:4)
如果要向表中添加一个自动更新为其他列的一半的列,则可以使用触发器执行此操作。
但我认为已经提出的答案是更好的方法。
干编码触发器:
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;
我不认为你只能做一次触发,因为我们必须回应的事件是不同的。
答案 5 :(得分:3)
我希望这仍然有助于某些人可能会接触到这篇文章。如果您需要计算列,为什么不在视图中公开您想要的列?不要只使用触发器保存数据或使性能过载......只需在视图中公开您已经格式化/计算过的数据。
希望这会有所帮助......
答案 6 :(得分:1)
您可以使用MYSQL 5.7中生成的列。
示例用法:
ALTER TABLE tbl_test
ADD COLUMN calc_val INT
GENERATED ALWAYS AS (((`column1` - 1) * 16) + `column2`) STORED;
虚拟 / 存储