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 に答える