我正在创建一个查询生成器,它将业务规则转换为针对Oracle数据库运行的SQL查询。规则基本上是“符合这些标准的所有项目应与符合这些标准的项目相关”的形式。经过深思熟虑和审议后,我确定最好的方法是使用SQL连接两组:
B必须是A的子集。我将通过从A减去B并期望空集来确定是否满足规则。如果集合不为空,则不符合规则。
“SQL连接”有许多Google图像结果,显示如何使用不同类型的连接语句表示各种集合关系,例如this image。我想要的(对于A - B)将是左边的中间位置:
select A.id
from items A
left join items B
on A.id = B.id
where B.id = null
显然我的查询比这复杂得多。我这样做的方法是将B作为子查询。我还必须包括关系表,然后添加标准。生成的模板:
select A.id
from items A
left join (
select A.id
from items A
join relationships rel
on rel.from_item = A.id
join items to
on rel.to_item = to.id
where [from criteria]
and [to criteria]
) B
on A.id = B.id
join relationships rel
on rel.from_item = A.id
where B.id = null
and [from criteria]
在语法上,我是否有更好的方法来执行我想要执行的查询?
我正在想象一下我可以将查询A构造为类似临时表的东西,然后从查询A构造查询B,然后让一个最终查询将它们连接在一起并返回结果。这可能吗?
答案 0 :(得分:2)
听起来你想要子查询因子 - WITH
子句
WITH first_set AS (
select A.id
from items A
join relationships rel
on rel.from_item = A.id
join items to
on rel.to_item = to.id
where [from criteria]
),
second_set AS (
select a.id
from first_set a
where [to criteria]
)
SELECT a.id
FROM first_set a
left join second_set b
on a.id = b.id
WHERE b.id IS NULL
就个人而言,在构建最终查询以使用NOT EXISTS
或MINUS
而非执行LEFT JOIN
并检查NULL
时,我会发现更清楚。 LEFT JOIN
方法有效,可能与其他方案一样有效。它总是让我觉得有点违反直觉。