我有以下 SQL
SELECT tsd.ID
FROM test_series_details tsd
WHERE tsd.DIV_ID =1
AND tsd.END_DATE > NOW()
AND tsd.ID NOT IN
((SELECT tsr.TEST_ID
FROM test_series_results tsr
WHERE tsr.STUDENT_ID=3)
UNION
(SELECT tsrlv.TEST_ID
FROM test_series_restore_log_viewer tsrlv
WHERE tsrlv.STUDENT_ID=3
GROUP BY tsrlv.TEST_ID))
我已经测试了以下部分查询并且它正在工作,
(SELECT tsr.TEST_ID
FROM test_series_results tsr
WHERE tsr.STUDENT_ID=3)
UNION
(SELECT tsrlv.TEST_ID
FROM test_series_restore_log_viewer tsrlv
WHERE tsrlv.STUDENT_ID=3
GROUP BY tsrlv.TEST_ID)
但是如何将这个 UNION 的输出提供给 IN 条件呢?
错误如下
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION (SELECT tsrlv.TEST_ID FROM test_series_restore_log_viewer tsrlv ' at line 9
最佳答案
最好的写法是作为两个单独的子句:
SELECT tsd.ID
FROM test_series_details tsd
WHERE tsd.DIV_ID = 1 AND
tsd.END_DATE > NOW() AND
tsd.ID NOT IN (SELECT tsr.TEST_ID
FROM test_series_results tsr
WHERE tsr.STUDENT_ID = 3
) AND
tsd.ID NOT IN (SELECT tsrlv.TEST_ID
FROM test_series_restore_log_viewer tsrlv
WHERE tsrlv.STUDENT_ID = 3
);
这允许引擎利用两个表上的索引。此外,GROUP BY
不是必需的(无论是这样编写还是在原始公式中)。
为了性能——并且以防万一子查询中的 id 可能为 NULL
——我倾向于使用 NOT EXISTS
来编写它:
SELECT tsd.ID
FROM test_series_details tsd
WHERE tsd.DIV_ID = 1 AND
tsd.END_DATE > NOW() AND
NOT EXISTS (SELECT 1
FROM test_series_results tsr
WHERE tsr.STUDENT_ID = 3 and tsr.TEST_ID = tsd.ID
) AND
NOT EXISTS (SELECT 1
FROM test_series_restore_log_viewer tsrlv
WHERE tsrlv.STUDENT_ID = 3 and tsrlv.TEST_ID = tsd.ID
);
此查询的最佳索引是:test_series_results(test_id, Student_id)
和 test_series_restore_log_viewer(test_id, Student_id)
和 test_series_details(DIV_ID, end_date, id)
.
关于MySQL,如何将 UNION 的输出提供给 WHERE 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30347216/