2017-07-16 163 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

查詢仍然會產生錯誤的結果,如上所述。 –