如何在Arel中使用"where exists"语句

17

如何在Arel中进行“where exists”查询?例如,在查询中显示至少有一个订单的所有供应商:

SELECT *
FROM suppliers
WHERE EXISTS
  (SELECT *
    FROM orders
    WHERE suppliers.supplier_id = orders.supplier_id);

我在 Arel 文档中看到了 "exists" http://rubydoc.info/gems/arel/2.0.7/Arel/Nodes/Exists,但是我在使用它时遇到了一些问题。


2
所涉及的关系运算符是半连接 - onedaywhen
1
我也对此很感兴趣。然而,似乎exists节点已经从ARel的最新版本中移除了。不确定未来是否有计划加入它。 - brad
2个回答

27

给你:

suppliers= Supplier.arel_table
orders= Order.arel_table
suppliers_with_orders = Supplier.where(
                          Order.where(orders[:supplier_id]
                                        .eq(suppliers[:id])).exists).to_sql =>
"SELECT `suppliers`.* FROM `suppliers` 
 WHERE (EXISTS (SELECT `orders`.* 
                FROM `orders` 
                WHERE `suppliers`.`id` = `orders`.`supplier_id`))"

然而,使用内联结会更加简单,但是最终的性能可能会更差:

Supplier.joins :orders


好的!在你提供关于“not exists”的链接之后,我正要回答这个问题。再次感谢 @pedrorolo。 - brad
3
内连接基本上是不同的,因为它会返回供应商记录的多个副本,每个订单都有一个。这将是一场性能灾难,特别是当您结合多个关联的存在测试时,其中10个订单、5个付款和20个交付组合在一起会返回1,000条记录。在几乎所有方面,“Exists”都更有效率。 - David Aldridge
我在Rails 7中尝试过,只能在内部子句中使用arel_table才能使其正常工作。Supplier.where(orders.where(orders[:supplier_id]... - sandro d.

-2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接