0

我已将以下查询从 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 语句会花费无尽的时间。但是当我用存在替换它时,它会给出不同的输出。

任何帮助将不胜感激。

4

1 回答 1

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在子查询中使用以避免结果中的行相乘。

于 2013-06-07T05:50:51.433 回答