代码之家  ›  专栏  ›  技术社区  ›  Daniel V

使用空值更新coalesce查询

  •  0
  • Daniel V  · 技术社区  · 5 年前

    当然是个基本问题,但我找不到一个例子。

    我正在写一个过程,它将两行合并为一行。它将所有子行的ID移动到正确的ID,替换所有子行的ID NULL 在最后删除“坏”行之前,将删除行中具有可用值的值。

    到目前为止,我得到的是:

    CREATE DEFINER=`danielv`@`%` 
    PROCEDURE `emp_merge`(IN `@core_emp_id` int, IN `@bad_emp_id` int)
    BEGIN
        UPDATE claim SET employee_id = @core_emp_id 
        WHERE employee_id = @bad_emp_id;
    
        WITH bad_employee_values AS (
            SELECT * FROM employee WHERE employee_id = @bad_emp_id
        )
        UPDATE employee SET 
                employee.employment_date = COALESCE(employee.employment_date, bad_employee_values.employment_date),
        WHERE employee_id = @core_emp_id;
    
        DELETE FROM employee WHERE employee_id = @bad_emp_id;
    
    END
    

    但是,我收到了非描述性错误消息,我不知道为什么。我怀疑我如何处理CTE和联合功能存在问题,但我不确定我理解中的差距在哪里。

    1 回复  |  直到 5 年前
        1
  •  1
  •   GMB    5 年前

    在本声明中:

    WITH bad_employee_values AS (SELECT * FROM employee WHERE employee_id = @bad_emp_id)
    UPDATE employee SET 
            employee.employment_date = COALESCE(employee.employment_date, bad_employee_values.employment_date),
    WHERE employee_id = @core_emp_id;
    

    您正在定义CTE bad_employee_values 但是你没有在 UPDATE 查询的一部分,因此不能访问其列:对于MySQL, bad_employee_values.employment_date 是未知的。

    看起来你可以在这里简单地避开CTE。你可以自己加入,就像这样:

    UPDATE employee e_core
    INNER JOIN employee e_bad ON e_bad.employee_id = @bad_emp_id
    SET e_core.employment_date = e_bad.employment_date,
    WHERE employee_id = @core_emp_id AND e_core.employment_date IS NULL
    

    此查询将简单地选择 @core_emp_id ,将其与相应的“坏”记录连接,并复制 employment_date . 第二个条件 WHERE 子句防止记录 就业日期 所选内容不为空。