我对 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);
我想要这个预期结果,但月薪还没有更新,是否可以显示它并更新monthly_salary?
最佳答案
您无法在单个查询中同时执行这两项操作。通常,人们会运行“选择查询”来检查所需的逻辑是否正确,例如
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 子句
,它查找开始日期早于今天(24 个月)的任何员工。
如果该逻辑正确,则在“更新查询”中应用相同的逻辑:
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()
要求子查询返回的所有值都等于 xhaving 子句
不仅仅是where 子句
的替代品。 having 子句旨在评估聚合数据,例如有 count(*) > 2
最后,虽然使用having子句很有创意,但您所做的是获得对别名“duration_months”的访问权限,因此您可以简单地这样做:
where TIMESTAMPDIFF(month,ep.start_date,curdate()) > 24
但是这不是过滤信息的好方法,因为它需要在做出决定之前对每一行数据运行一个函数。这会导致查询变慢。将其与以下内容进行比较:
WHERE ep.start_date < curdate() - INTERVAL 24 MONTH
ep.start_date
不受任何函数的影响,并且 curdate() - INTERVAL 24 MONTH
只是一次计算(并非每行都进行)。因此,这更加高效(也称为“sargable”)。
关于MYSQL 更新包含联接和子查询的表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47585595/