Oracle - 可以简化或重新组织此查询吗?

时间:2014-07-21 18:39:50

标签: sql oracle join set alias

我正在创建一个查询生成器,它将业务规则转换为针对Oracle数据库运行的SQL查询。规则基本上是“符合这些标准的所有项目应与符合这些标准的项目相关”的形式。经过深思熟虑和审议后,我确​​定最好的方法是使用SQL连接两组:

  1. 与FROM条件(A)匹配的所有项目的集合
  2. 与符合TO标准(B)
  3. 的项目相关的FROM条件匹配的所有项目的集合

    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,然后让一个最终查询将它们连接在一起并返回结果。这可能吗?

1 个答案:

答案 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 EXISTSMINUS而非执行LEFT JOIN并检查NULL时,我会发现更清楚。 LEFT JOIN方法有效,可能与其他方案一样有效。它总是让我觉得有点违反直觉。