【问题标题】:UPDATE TABLE WITH CASE更新表与案例
【发布时间】:2016-09-07 10:39:12
【问题描述】:
我有两张桌子user_master 和login_history。
在User_master 我想更新status 列为 A(absent) 或 P(Present) 如果用户在当前日期登录历史。
我正在尝试的代码,但它会更新所有行。我想要的是如果用户已经登录,它应该匹配两个表并将user_masterstatus 列更新为 P 或 A。
希望我的问题很清楚。帮助将不胜感激。这是我的 MySQL 查询
UPDATE User_master a
INNER JOIN
(
SELECT DISTINCT user_name FROM login_history WHERE DATE(`login_time`)=CURRENT_DATE()
) b
SET a.`user_status` = CASE
WHEN a.`user_name`=B.`user_name` THEN 'P'
WHEN a.`user_name`!=B.`user_name` THEN 'A'
END
【问题讨论】:
标签:
mysql
sql
stored-procedures
sql-update
case
【解决方案1】:
嗯,我在想LEFT JOIN:
UPDATE User_master m
LEFT JOIN Login_History lh
ON m.user_name = lh.user_name AND
DATE(lh.login_time) = CURRENT_DATE()
SET m.user_status = (CASE WHEN lh.user_name IS NULL THEN 'A' ELSE 'P' END);
我突然想到在给定日期可能有多个登录。结果是同一行上的其他更新。您可以通过以下方式防止这种情况:
UPDATE User_master m LEFT JOIN
(SELECT lh.user_name, 'P' as user_status
FROM Login_History lh
WHERE lh.login_time >= CURRENT_DATE() AND
lh.login_tie < DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY)
GROUP BY lh.user_name
) lh
ON m.user_name = lh.user_name
SET m.user_status = COALESCE(lh.user_status, 'A');
请注意,我也更改了日期算法。这个版本应该更好地利用索引。
【解决方案2】:
使用两个查询可能会更容易:
- 让所有人都缺席(更新 ... set user_status='A')
- 使用选择集将当前人员设置为 P。
像这样:
update user_master set user_status='A';
update user_master set user_status='P'
where user_name in (select distinct user_name from login_history...);
连接稍微快一些,但这是一种非常简洁、易于理解的方法。