MYSQL更新包含连接和子查询的表

时间:2017-12-01 02:05:06

标签: mysql sql

我对SQL比较陌生,我试图根据工作一段时间的员工更新月薪,查询使用来自人员和员工表的信息显示数据,但它不会更新,我保持得到一个'操作数应该包含1列'错误?我将如何显示所有数据并能够更新monthly_salary列?感谢。

 UPDATE employee ep set monthly_salary = monthly_salary*1.15 = all(
    SELECT p.person_id, p.name_first, p.name_last, ep.monthly_salary, ep.start_date, curdate() as today_date,
    TIMESTAMPDIFF(month,ep.start_date,curdate()) as duration_months 
    FROM employee ep
    INNER JOIN person p ON ep.person_id = p.person_id having duration_months > 24);

query result

我想要这个预期的结果,但月薪还没有更新,是否可以显示这个并更新monthly_salary?

1 个答案:

答案 0 :(得分:0)

您无法在单个查询中同时执行这两项操作。通常会运行一个"选择查询"检查所需的逻辑是否正确,例如

SELECT
        p.person_id
      , p.name_first
      , p.name_last
      , ep.start_date
      , curdate() as today_date
      , TIMESTAMPDIFF(month,ep.start_date,curdate()) as duration_months 
FROM employee ep
INNER JOIN person p ON ep.person_id = p.person_id 
WHERE ep.start_date < curdate() - INTERVAL 24 MONTH
;

在该查询中,重要的逻辑是where clause,它寻找的开始日期早于今天 - 24个月。

如果该逻辑是正确的,那么在&#34;更新查询中应用相同的逻辑&#34;:

UPDATE employee ep 
SET monthly_salary = monthly_salary*1.15 
WHERE ep.start_date < curdate() - INTERVAL 24 MONTH
;

语法注释:

  • 你不能使用多个相等运算符将多个条件串在一起(monthly_salary = monthly_salary*1.15 = all(...) ,其中有2个=符号
  • x = all()要求子查询返回的所有值都等于x
  • having clause不仅仅是where clause的替代品。 having子句用于评估聚合数据,例如having count(*) > 2

最后,虽然使用having子句是有创造性的,但你正在做的是获得别名&#39; duration_months&#39;,所以你可以简单地做到这一点:

where TIMESTAMPDIFF(month,ep.start_date,curdate()) > 24

但是这不是过滤信息的好方法,因为它需要在达到决策之前在每一行数据上运行一个函数。这有助于减慢查询速度。将其与以下内容进行比较:

WHERE ep.start_date < curdate() - INTERVAL 24 MONTH

ep.start_date不受任何函数的影响,curdate() - INTERVAL 24 MONTH只是一次计算(不是每行都进行)。所以这更有效率(也称为&#34; sargable&#34;)。