SQL 通过多对多关系查询
SQL querying through a many to many relationship
我有一个多对多 relationship 由三个表表示:quote
、payment
和 quote_payment
因为报价可以有多次付款尝试,并且一次付款可以用于多个引号。我的目标是查询 return 所有已付款或未付款的报价单。
因此,如果报价至少有一笔付款,其中 is_paid = true 它应该在我查询已付款的报价时显示一次,如果没有,它应该在我查询时显示一次我正在尝试获取尚未支付的报价。
目前,我有这个用于显示已支付报价的查询:
select distinct quote.name, payment.is_paid from quote
join quote_payment on (quote.id = quote_payment.quote_id)
join payment on (payment.id = quote_payment.payment_id)
where payment.is_paid is true;
对于那些还没有付款的人来说:
select distinct quote.name, payment.is_paid from quote
join quote_payment on (quote.id = quote_payment.quote_id)
join payment on (payment.id = quote_payment.payment_id)
where payment.is_paid is false;
问题是当我尝试获取尚未支付的报价时。例如,如果一个报价有一个失败的付款和另一个成功的付款,那么它不应该显示在对尚未支付的报价的查询中。
我还尝试将 is_paid 列放在 quote
中,而不是 payment
,但这需要我在每次付款时更新与付款相关的所有报价是成功的,但也许这就是我应该做的。考虑到此架构,您将如何继续获取没有任何成功付款的报价?
Here's the schema with example data and some attempts I've made.
使用聚合。每次付款都return一个标志:
select q.name, max(p.is_paid) as is_paid
from quote q join
quote_payment qp
on q.id = qp.quote_id join
payment p
on p.id = qp.payment_id
group by q.name;
要过滤,请使用 having
子句。 . . having max(p.is_paid) = 0
例如。
我有一个多对多 relationship 由三个表表示:quote
、payment
和 quote_payment
因为报价可以有多次付款尝试,并且一次付款可以用于多个引号。我的目标是查询 return 所有已付款或未付款的报价单。
因此,如果报价至少有一笔付款,其中 is_paid = true 它应该在我查询已付款的报价时显示一次,如果没有,它应该在我查询时显示一次我正在尝试获取尚未支付的报价。
目前,我有这个用于显示已支付报价的查询:
select distinct quote.name, payment.is_paid from quote
join quote_payment on (quote.id = quote_payment.quote_id)
join payment on (payment.id = quote_payment.payment_id)
where payment.is_paid is true;
对于那些还没有付款的人来说:
select distinct quote.name, payment.is_paid from quote
join quote_payment on (quote.id = quote_payment.quote_id)
join payment on (payment.id = quote_payment.payment_id)
where payment.is_paid is false;
问题是当我尝试获取尚未支付的报价时。例如,如果一个报价有一个失败的付款和另一个成功的付款,那么它不应该显示在对尚未支付的报价的查询中。
我还尝试将 is_paid 列放在 quote
中,而不是 payment
,但这需要我在每次付款时更新与付款相关的所有报价是成功的,但也许这就是我应该做的。考虑到此架构,您将如何继续获取没有任何成功付款的报价?
Here's the schema with example data and some attempts I've made.
使用聚合。每次付款都return一个标志:
select q.name, max(p.is_paid) as is_paid
from quote q join
quote_payment qp
on q.id = qp.quote_id join
payment p
on p.id = qp.payment_id
group by q.name;
要过滤,请使用 having
子句。 . . having max(p.is_paid) = 0
例如。