我有以下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条件?
错误如下
错误代码:1064。您的SQL语法有错误;检查 手册,对应右边的MySQL服务器版本 在&UNION附近使用的语法(SELECT tsrlv.TEST_ID FROM test_series_restore_log_viewer tsrlv'在第9行
答案 0 :(得分:2)
写这个的最好方法是两个单独的条款:
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)
。
答案 1 :(得分:1)
尝试使用LEFT JOIN
,如下所示
SELECT tsd.ID
FROM test_series_details tsd
LEFT JOIN ((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)) AS T on T.TEST_ID = tsd.ID
WHERE tsd.DIV_ID =1
AND tsd.END_DATE > NOW()
AND T.TEST_ID is null
答案 2 :(得分:1)
现在怎么样 -
SELECT tsd.ID
FROM test_series_details tsd
WHERE
tsd.DIV_ID =1
AND tsd.END_DATE > NOW()
AND tsd.ID NOT IN (
select TEST_ID from (
(
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
)
)x
)
答案 3 :(得分:0)
试试这个
SELECT tsd.ID
FROM test_series_details tsd
WHERE tsd.DIV_ID =1
AND tsd.END_DATE > NOW()
AND tsd.ID NOT IN
(
select TEST_ID from (
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
)as alias
)