如何将列的值设置为sql查询?

时间:2014-04-11 21:06:21

标签: mysql sql

我有两个表 x y 我希望将x中的列设置为y列中按公共列分组的平均值。

这就是我迄今所做的事情

update
set x.column2 = (SELECT AVG(NULLIF(column2,0)) 
             FROM y group by column1)
                 on (x.column1 = y.column1)

我希望每当y.column2的任何一行的值发生变化时,x.column2的值都会自动更新。

注意:两个表中没有列具有相同的名称。

2 个答案:

答案 0 :(得分:1)

UPDATE 
  x
SET 
  x.column2 = (SELECT AVG(NULLIF(column2,0)) 
               FROM y 
               WHERE y.column1 = x.column1)

这将在x中每行运行子查询一次,但子查询仅限于y中的行,其中column1与当前的x.column1匹配。

对于好奇的人来说,这个内部更深一些。通常,所有查询(甚至是子查询)都返回类似于表的对象(关系中的“关系”)。如果结果只有一行,则可以将其强制转换为“行”(关系中的“tuple”)。如果元组只有一列,则可以进一步强制转换为该列中的值。这就是这里发生的事情。此外,不需要显式的“分组依据”,因为WHERE子句将子查询限制为仅我们想要求和的行,因此我们利用隐含的“组所有行”行为(类似于添加GROUP BY y.column1

在您发表评论之后,我想展示如何为同一事物创建“视图”,这在MySQL中意味着聚合值实际上并未“存储”,而是实时计算。这意味着当你插入y时它永远不会过时。

CREATE VIEW vx AS SELECT column1, AVG(NULLIF(column2,0) as avg FROM y GROUP BY y.column1

然后,您可以从vx中进行选择,并在后台运行该查询。

答案 1 :(得分:0)

您需要触发器 - 请参阅here

在你的情况下像

CREATE TRIGGER name AFTER INSERT ON y FOR EACH ROW BEGIN [above statement] END
CREATE TRIGGER name AFTER UPDATE ON y FOR EACH ROW BEGIN [above statement] END
CREATE TRIGGER name AFTER DELETE ON y FOR EACH ROW BEGIN [above statement] END

我没有试过这个,所以不能保证没有语法错误(但不应该)。