postgresql一些和所有

时间:2014-07-12 15:08:04

标签: ruby-on-rails postgresql

所以我试图获得两个独立的价值观。已完成所有付款的发票和已支付部分付款的发票。 这是一个rails应用程序

Invoices has_many :payments

支付付款:真实或付款:虚假。 因此,在我的第一次通话中,我希望获取已完成所有付款的那些发票的发票ID。我试过了:

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]))

不幸的是,即使支付了3分中的2分,这也会为发票返回一行:true

接下来的电话是获得一些付款的发票:真实,有些付款:假。为此,我尝试过:

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 个答案:

答案 0 :(得分:1)

=ALL (array[...])表示等于数组的所有元素,当数组只有一个元素时,它等同于简单的相等测试。

因此payments.paid = ALL(array[true])相当于payments.paid = true

通过类似的逻辑,payments.paid = SOME(array[false])相当于payments.paid = false

此查询似乎不需要或不需要数组和ALL / SOME。它可以这样表达:

"查找没有付款的相应付款的发票= 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 = true的付款计数的发票(意味着全部付款)"

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为真时,

p.paid::int求值为1,当p.paid为假时,

having求值为0

对于其他查询,您可以使用having sum(P.paid::int)<count(*)子句。 例如,{{1}}将仅保留付款金额小于此发票付款次数的发票,这意味着它们并未完全支付。