在不使用联合的情况下获得类似联合的结果

Posted

技术标签:

【中文标题】在不使用联合的情况下获得类似联合的结果【英文标题】:Get a union-like result without using union 【发布时间】:2015-03-09 15:26:14 【问题描述】:

这是我的表结构:

Product(ID, Barcode, Name)

ChildProduct(ProductID, Barcode)

ChildProduct(ProductID) REFERENCES Product(ID)

这是一些示例数据:

Product
(1,100,'A')
(2,200,'B')
(3,300,'C')
(4,400,'D')

ChildProduct
(1,101)
(1,102)
(2,201)
(4,401)

这是想要的结果:

(1,100,'A')
(1,101,'A')
(1,102,'A')
(2,200,'B')
(2,201,'B')
(3,300,'C')

这可以通过联合很容易地实现:

SELECT * FROM Product
WHERE ID IN (1,2,3)
UNION
SELECT * FROM ChildProduct cp
JOIN Product p ON (p.Id = cp.ProductID)
WHERE p.ProductID IN (1,2,3)

然而,实际上,这个查询的WHERE 部分是一个复杂的连接构造,所以我真的很想避免使用UNION,这样我就不必复制所有代码了。

如何在不复制 where 子句的情况下获得相同的结果?

编辑:看起来我简化了一点。我稍微调整了一下,表明无论如何我都必须加入 ChildProduct 和 Product。

我真正在寻找的是一种彻底解除工会的方法。

【问题讨论】:

对整个联合查询应用where 子句。 Oracle 应该能够单独下推每个查询中的限制。 【参考方案1】:

您可以对派生表执行 UNION 并查询:

SELECT * FROM
    (SELECT Id, Barcode FROM Product
    UNION ALL
    SELECT ProductId, Barcode FROM PRODUCT) AS ProductAndChild
WHERE ProductAndChild.Id IN (1,2,3)

UNION ALLUNION 快​​,所以如果您知道不会出现重复,或者重复无关紧要,则最好使用)

【讨论】:

我想我可能把我的用例简化了一点。有什么办法可以完全解除工会?【参考方案2】:

并不是说我推荐这是一个更快的选项 .. 但是,您可以使用 FULL OUTER JOIN ... O.o 复制结果

不确定您为什么要这样做... [编辑] 没有注意到 OP 用于简化 where ...稍微调整的目的 - 使用 David 的回答 .. 它解决了您的根本问题: ) [/编辑]

  select * from (
  select nvl(p.id,cp.productid) id,
         nvl(p.barcode, cp.barcode) barcode
    from product p
      full outer join 
           childproduct cp
        on p.id = cp.productid
          and p.barcode = cp.barcode
     )
   where id in (1,2,3)
  /

          ID    BARCODE
  ---------- ----------
           1        101
           1        102
           2        201
           2        200
           1        100
           3        300

  6 rows selected.

[edit] 调整了查询​​以“简化”最终的 where .. 不过,这也可以通过 union 来完成: 选择 * 从 ( 选择 ) 联盟 选择 )

变化不大……

【讨论】:

以上是关于在不使用联合的情况下获得类似联合的结果的主要内容,如果未能解决你的问题,请参考以下文章

在JavaScript中获得两个数组的联合[重复]

我们如何在不使用联合子句的情况下使用 rownum 显示给定表的第一行和最后一行

在联合之后只返回一条记录

将联合与laravel结合使用时如何获得两个不同表的总和

如何获得几个 immutable.js 列表的联合

联合两个查询结果按列