在mysql查询中EXISTS给出了错误的结果

时间:2013-06-07 05:42:47

标签: mysql

我已经将以下查询从mssql迁移到mysql。

SELECT employee.ecode, fname, mname, lname
FROM employee
WHERE employee.cmp_dol IS NULL
 AND employee.ecode IN
     (SELECT leave_log.ecode
      FROM leave_log
      WHERE (l_acc_code = 11 OR l_acc_code = 21 OR l_acc_code = 31 OR l_acc_code = 41 OR l_acc_code = 51 OR l_acc_code = 61 )
      GROUP BY leave_log.ecode, l_date, l_acc_code
      HAVING SUM(l_value) <> 0)
 AND employee.ecode IN ((SELECT ecode
                         FROM emp_supervisor
                         WHERE sup_id = @ecode
                         AND emp_sup_dol IS NULL)
                        UNION
                        (SELECT ecode
                         FROM emp_project
                         WHERE proj_emp_dol IS NULL
                         AND pid IN (SELECT pid
                                     FROM proj_supervisor
                                     WHERE proj_sup_dol IS NULL
                                     AND sup_id =@ecode
                                     AND pid IN (SELECT pid
                                                 FROM projects
                                                 WHERE p_end_date IS NULL
                                                 AND leave_flag=1))))
ORDER BY fname

在查询中使用IN语句需要花费无尽的时间。 但是,当我用存在替换它时,它会给出不同的输出。

任何帮助都将受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

MySQL在使用子查询优化WHERE IN方面非常差,而是使用JOIN:

SELECT employee.ecode, fname, mname, lname
FROM employee
JOIN (SELECT DISTINCT ecode
      FROM emp_supervisor
      WHERE sup_id = @ecode
      AND emp_sup_dol IS NULL
     UNION DISTINCT
     SELECT DISTINCT ecode
      FROM emp_project
      WHERE proj_emp_dol IS NULL
      AND pid IN (SELECT pid
                  FROM proj_supervisor
                  WHERE proj_sup_dol IS NULL
                  AND sup_id =@ecode
                  AND pid IN (SELECT pid
                              FROM projects
                              WHERE p_end_date IS NULL
                              AND leave_flag=1))) e
ON employee.ecode = e.ecode
JOIN (SELECT DISTINCT ecode
      FROM (SELECT leave_log.ecode
            FROM leave_log
            WHERE (l_acc_code IN (11, 21, 31, 41, 51, 61)
            GROUP BY leave_log.ecode, l_date, l_acc_code
            HAVING SUM(l_value) <> 0) x) l
ON employee.ecode = l.ecode
WHERE employee.cmp_dol IS NULL
ORDER BY fname

如果子查询有重复项,则需要在子查询中使用DISTINCT以避免在结果中乘以行。