从另一列计算的列?

Mat*_*hew 58 mysql sql

鉴于下表:

id | value
--------------
1     6
2     70
Run Code Online (Sandbox Code Playgroud)

有没有办法添加一个根据同一个表中的另一列自动计算的列?像VIEW,但同一个表的一部分.举个例子,calculated就是一半value.Calculated应该在value更改时自动更新,就像VIEW一样.

结果将是:

id | value | calculated
-----------------------
1     6       3
2     70      35
Run Code Online (Sandbox Code Playgroud)

Abh*_*pta 59

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);
Run Code Online (Sandbox Code Playgroud)

金额将自动弹出表格,您可以直接访问它,另请注意,无论何时更新任何列,金额也会更新.


Vin*_*rat 33

如果是选择,您可以这样做:

SELECT id, value, (value/2) AS calculated FROM mytable
Run Code Online (Sandbox Code Playgroud)

否则,您还可以先更改表以添加缺少的列,然后执行UPDATE查询以计算新列的值,如下所示:

UPDATE mytable SET calculated = value/2;
Run Code Online (Sandbox Code Playgroud)

如果它必须是自动的,并且您的MySQL版本允许它,您可以尝试使用触发器

  • 是的,这是一个SELECT,而不是向表中添加一列. (7认同)
  • 你可以使用`calculated`列在同一个查询中运行进一步的计算吗?喜欢(`calculated`*2)AS`double_calculated`? (4认同)

Jon*_*len 24

MySQL 5.7支持计算列.他们称之为"Generated Columns",语法有点奇怪,但它支持我在其他数据库中看到的相同选项.

https://dev.mysql.com/doc/refman/5.7/en/create-table.html#create-table-generated-columns


Jer*_*rry 21

@krtek的答案是正确的方向,但有几个问题.

坏消息是在同一个表的触发器中使用UPDATE将不起作用.好消息是没有必要; 在触摸桌子之前,您可以操作一个新对象.

触发器变为:

CREATE TRIGGER halfcolumn_update BEFORE UPDATE ON my_table
  FOR EACH ROW BEGIN
    SET NEW.calculated = NEW.value/2;
  END;
Run Code Online (Sandbox Code Playgroud)

还要注意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 ;
Run Code Online (Sandbox Code Playgroud)

  • 注意:在上面的代码中,将"table"替换为您的表名.我以为作者只是忘记了表名,并在"ON table"之后添加了它并浪费了几分钟. (3认同)

Pod*_*.io 13

您可以使用 MYSQL 5.7 中生成的列。

示例用法:

ALTER TABLE tbl_test
ADD COLUMN calc_val INT 
GENERATED ALWAYS AS (((`column1` - 1) * 16) + `column2`) STORED;
Run Code Online (Sandbox Code Playgroud)

虚拟/存储

  • 虚拟:从表中读取记录时动态计算(默认)
  • 存储:在表中插入/更新新记录时计算


krt*_*tek 5

如果您想向表中添加一列,该列会自动更新为其他列的一半,您可以使用触发器来实现。

但我认为已经提出的答案是更好的方法。

干编码触发器:

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;
Run Code Online (Sandbox Code Playgroud)

我不认为你只能触发一个,因为我们必须响应的事件是不同的。