带案例的更新表

时间:2016-09-07 10:39:12

标签: mysql sql stored-procedures sql-update case

我有两张表user_masterlogin_history
User_master我想将status列更新为 A(缺席) P(现在),如果用户已登录在登录历史的当前日期。
我正在尝试的代码,但它会更新所有行。我想要的只是如果用户已登录,则应该同时匹配这两个表并将user_master status列更新为 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

2 个答案:

答案 0 :(得分:3)

嗯,我在想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');

请注意,我也改变了日期算术。这个版本应该更好地利用索引。

答案 1 :(得分:0)

两个查询可能会更容易:

  1. 设置每个人缺席(更新...设置user_status ='A')
  2. 使用选择集将当前人员设置为P.
  3. 像这样:

    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...);
    

    联接更快一点,但这是一种非常干净,易懂的方法。