2014-07-12 69 views
0

所以我試圖得到兩個獨立的值。已完成所有付款的發票和已完成付款的發票。 這是一個Rails應用程序,以便postgresql部分和全部

Invoices has_many :payments 

付款要麼支付:true或支付:假的。 因此,在我第一次打電話時,我想要獲得所有付款的發票的發票編號。我已經試過:

SELECT DISTINCT (invoices.id) FROM "invoices" join payments on payments.invoice_id = invoices.id WHERE "invoices"."payer_id" = 1 AND (payments.paid = ALL(array[true])) 

不幸的返回一行發票即使2出3支付:真正

下一次調用是讓其中一些被支付的發票:真實的,有些是支付:假的。爲此,我已經試過:

SELECT DISTINCT (invoices.id) FROM "invoices" join payments on payments.invoice_id = invoices.id WHERE "invoices"."payer_id" = 1 AND (payments.paid = SOME(array[true]) AND payments.paid = SOME(array[false])) 

但這不會返回即使一些從該發票付款的支付行,而有些則沒有。

我是否正確使用ALL和SOME?還是有另一種方式來打這個電話?看起來像一個相當直接的電話,所以我相信有一些方法可以做到這一點。謝謝大家幫助!

回答

1

=ALL (array[...])意味着等於數組的所有元素,而當數組只有一個元素時,它相當於一個簡單的相等性測試。

所以payments.paid = ALL(array[true])相當於payments.paid = true

並且通過類似的邏輯,payments.paid = SOME(array[false])相當於payments.paid = false

對於此查詢,數組和全部/某些似乎不需要或不可取。它可表示如下:

「找發票,其有沒有相應的付款支付=假」

select distinct I.id 
from invoices I 
where payer_id=1 
and not exists (select 1 FROM payments P WHERE P.invoice_id=I.id AND P.paid=false); 

一種不同的方式來表達它:

「查找發票時計數支付等於與p.paid付款=真的計數(意味着付款均由)」

select I.id 
from invoices I join payments P on (I.id=P.invoice_id) 
group by I.id 
having sum(P.paid::int)=count(*); 

p.paid::int的計算結果爲1時p.paid爲真,並在p.paid爲假時爲0

對於其他查詢,您可以使用having子句進行操作。 例如having sum(P.paid::int)<count(*)將只保留支付付款次數少於此發票付款次數的發票,這應該表示它們沒有全部付款。

+0

啊完美,謝謝我沒想到有。從MySql切換到PG,我覺得很困難。愚蠢的英雄。 –