我正在使用一个中等大小的MSAccess .mdb文件,我需要使用SQL进行操作。不幸的是,一些在理论上起作用的陈述似乎导致它挂起,而且我遇到了一堵砖墙。
Here is a simplified representation in SQL Fiddle
三个表:products,product_category和categories 我需要SELECT类别只包含字段'HIDE = 1'的项目 如果某个类别包含hide = 0的产品,则不应选择该类别。
我可以使用子查询相对容易地完成此操作,但查询会停止。在过去,依赖于左连接的查询似乎可以有效地执行,但是我无法将连接包围足以将此查询转换为该格式。
编辑:
SELECT c.categoryid
FROM product_category AS c
LEFT JOIN
(
SELECT DISTINCT c.categoryid
FROM product_category AS c
LEFT JOIN products AS p
ON c.catalogid = p.catalogid
WHERE p.hide = 0
) y ON y.categoryid = c.categoryid
WHERE y.categoryid IS NULL
有人将上述查询作为答案发布,但由于某种原因将其删除。据我所知,它的工作和工作很快。我认为这个问题有待回答。如果我记得,一旦计时器允许,我会自行发布答案。
答案 0 :(得分:2)
我相信你只需要关联子查询,例如......
SELECT c.categoryid FROM product_category AS c
WHERE c.categoryid NOT IN
(SELECT DISTINCT c1.categoryid FROM product_category AS c1
LEFT JOIN products AS p ON c1.catalogid = p.catalogid
WHERE p.hide = 0)
注意我将子查询product_category
表别名为c1
而不是c
- 这意味着子查询只执行一次,而不是主查询的每一行执行一次
请注意,毫无疑问更多的效率仍然存在,但我认为这足以达到您的目的。
事实上,这里不需要LEFT JOIN,我不认为......
SELECT c.categoryid FROM product_category AS c
WHERE c.categoryid NOT IN
(SELECT DISTINCT c1.categoryid FROM product_category AS c1
INNER JOIN products AS p ON c1.catalogid = p.catalogid
WHERE p.hide = 0)
..这将为你提供一些额外的速度。
答案 1 :(得分:2)
如果每个catalogid只有一个categoryid,那么你可以摆脱不同的:
Select
c.id, c.categoryname
From
category c
Where
Not Exists (
Select
'x'
From
products p
Inner Join
product_category pc
on pc.catalogid = p.catalogid
Where
pc.categoryid = c.id and
p.hide = 0
)
编辑 - 小提琴中的测试数据似乎错了,我已经纠正了。这应该现在可以使用