2017-07-16 103 views
1

协会下面是一些背景的小数据库架构ActiveRecord的 - 查询与多个条件对

Order 
    -> id 
LineItem 
    -> id 
    -> order_id 
Transaction 
    -> id 
    -> transaction_type 
    -> successful 
    -> line_item_id 

基本上,我们正在试图做的是获取具有多个交易的所有订单,在符合特定条件对交易

这里是作为一个例子来使用一个非常基本的表模式:

Order (orders) 
+----+ 
| id | 
|----| 
| 1 | 
| 2 | <-- 
| 3 | 

Line Items (line_items) 
+---------------+ 
| id | order_id | 
|----|----------| 
| 1 | 1  | 
| 2 | 2  | <-- 
| 3 | 3  | 

Transactions (transactions) 
+---------------------------------------------------+ 
| id | transaction_type | successful | line_item_id | 
|----|------------------|------------|--------------| 
| 1 | 2    | 1   | 1   | 
| 2 | 2    | 0   | 2   | <-- 
| 3 | 1    | 1   | 1   | 
| 4 | 3    | 1   | 2   | <-- 
| 5 | 1    | 1   | 3   | 
| 6 | 3    | 1   | 3   | 

我用箭头突出显示了我们将关注的记录。

Order类把更多的上下文:

class Order < ActiveRecord::Base 
    has_many :line_items 
    has_many :transactions, through: :line_items 
end 

正如我所说的,我们希望在transactions获取通过特定的约束条件(对)的所有订单。

所以我们只希望选择一个order如果我们有(At least ONE transaction with "transaction_type" = 2 AND "successful = 0"), AND (At least ONE transaction with "transaction_type" = 3 AND "successful" = 1)

不能OR。只有在遵守两个约束条件的情况下才能选择顺序。

(例如:我只想要订单,其中有订单项只有一个类型2的交易AND不成功)。 [这应该只给我订单,有单一类型的交易,但它可以有任何其他类型的交易]

我一直在搜索最近10小时如何实现这一点,无济于事,所以我转向你寻求答案。 如果您好奇:我们使用postgres

我甚至不知道从哪里开始查询,甚至不知道ActiveRecord语法。

问题的好例子: https://github.com/dsounded/ransack_example/blob/master/app/services/finder.rb#L7 问题在于无法命令或分页结果。

回答

1

您可以尝试加入事务与自身

Transactions.joins("INNER JOIN transactions as x ON x.line_item_id=transactions.line_item_id").where("transactions.transaction_type=2 AND transactions.successful=0").where("x.transaction_type=3 AND x.successful=1").includes(:order) 
+0

这样的查询结果:' SELECT COUNT(*)FROM“transactions”INNER JOIN transactions as x ON x.line_item_id = transactions.line_item_id WHERE(transactions.transaction_type = 2 AND transactions.successful ='f')AND(x.transaction_type = 3 AND x.successful = 't')' –

+0

成功fie的类型是什么在数据库中的ld? –

+0

这是布尔值。 'f'|| 't' –

0

你需要使用一个havingwhere联接,是这样的:在`nil`

Order.joins(line_items: :transactions).select("orders.*") 
.group("orders.id").having(count(transactions.id) > 2).where(your conditions) 
+0

'Order.joins(line_items :: transactions).select(“orders。*”)。group(“orders.id”)。having('count(transactions.id)> 2')。其中(“(transactions.transaction_type = 2 AND transactions.successful ='f')OR(transactions.transaction_type = 3 AND transactions.successful ='t')”)'会产生很多结果,因为一些订单可以有多个订单项与每个相同类型和成功的交易。因此它不会产生正确的结果。 –

+0

尝试'Order.left_outer_joins(..... same ...)',内部连接返回大量数据。 –

+0

查询仍然会产生错误的结果,如上所述。 –