这是我的数据库。FoodItems 只是普通表,但我想使用虚拟列来生成所有相关数据,例如 Servings.kcal 等于相关 (FieldItem.kcal*unit)/100(数据以每 100g/100ml 的千卡为单位指定):
CREATE TABLE IF NOT EXISTS `DietDB`.`Servings` (
`id` INT UNSIGNED NOT NULL,
`FoodItem_id` INT UNSIGNED NOT NULL,
`name` VARCHAR(255) NOT NULL,
`units` DOUBLE UNSIGNED NULL,
`kcal` INT GENERATED ALWAYS AS (SELECT (FoodItems.kcal*units)/100 FROM Servings JOIN FoodItems ON Servings.FoodItem_id = FoodItems.id) VIRTUAL,
`carbohydrate` DOUBLE UNSIGNED NULL,
`carbohydrate_sugar` DOUBLE UNSIGNED NULL,
`fat` DOUBLE UNSIGNED NULL,
`fat_saturated` DOUBLE UNSIGNED NULL,
`fat_trans` DOUBLE UNSIGNED NULL,
`protein` DOUBLE UNSIGNED NULL,
`fibre` DOUBLE UNSIGNED NULL,
PRIMARY KEY (`id`, `FoodItem_id`),
INDEX `fk_Servings_FoodItems1_idx` (`FoodItem_id` ASC),
UNIQUE INDEX `name_UNIQUE` (`name` ASC),
CONSTRAINT `fk_Servings_FoodItems1`
FOREIGN KEY (`FoodItem_id`)
REFERENCES `DietDB`.`FoodItems` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
Run Code Online (Sandbox Code Playgroud)
这显然是错误的,因为查询返回整个表,而不是单个值,并且它会大喊错误......但它展示了我试图在那里实现的目标。怎么可能呢?
根据 MySQL 文档,GENERATED
列不能有子查询:
生成的列表达式必须遵守以下规则。如果表达式包含不允许的结构,则会发生错误。
允许使用文字、确定性内置函数和运算符。如果给定表中相同的数据,多次调用会产生相同的结果,而与连接的用户无关,则该函数是确定性的。不符合此定义的函数示例:
CONNECTION_ID(), CURRENT_USER(), NOW()
。不允许使用子查询、参数、变量、存储函数和用户定义函数。
...
你可以做的是使用视图:
CREATE VIEW DietDB.Servings_All -- pick an appropriate name
AS
SELECT s.*,
CAST((fi.kcal * s.units) / 100 AS UNSIGNED INT) AS kcal
FROM DietDB.Servings AS s
LEFT JOIN DietDB.FoodItems AS fi
ON s.FoodItem_id = fi.id ;
Run Code Online (Sandbox Code Playgroud)