您可以使用 LEFT JOIN 代替子查询来执行此操作,并检查 NULL。
SELECT DISTINCT tp.template_id
FROM templateproduct tp
LEFT JOIN templateproduct tp2
ON tp.template_id = tp2.template_id AND tp2.prod_id IN (6, 7, 8, 9, 10)
WHERE tp.prod_id < 5
AND tp2.template_id IS NULL
您可以使用 GROUP BY 执行类似的操作,并检查是否有 0 个匹配的模板链接到排除的产品 ID:
SELECT tp.template_id
FROM templateproduct tp
LEFT JOIN templateproduct tp2
ON tp.template_id = tp2.template_id AND tp2.prod_id IN (6, 7, 8, 9, 10)
WHERE tp.prod_id < 5
GROUP BY tp.template_id
HAVING COUNT(tp2.template_id) = 0
根据您的数据和索引,这可能会或可能不会比子查询更有效 - 我建议您尝试一下。无论如何,根本没有理由使用任何 INNER JOIN 来获得您正在寻找的结果:
SELECT DISTINCT tp.template_id
FROM templateproduct tp
WHERE tp.prod_id < 5
AND tp.template_id NOT IN (
SELECT tp2.template_id FROM templateproduct tp2 WHERE tp2.prod_id IN (6, 7, 8, 9, 10)
)
试试这些,看看哪个更适合你。当然,请检查查询计划以了解原因。