我在这里讨论了几个主题,但是我无法让它发挥作用。对于每个"锅"我想获得与此底池相关的付款数量以及全额佣金(所有付款佣金的总和)。
SELECT id, id_user,
( SELECT IFNULL( SUM(amount), 0 ) AS collectedA,
IFNULL( SUM(commission), 0 ) AS commission
FROM payment AS pay WHERE pay.id_pot = pot.id AND pay.stat = 1 ) FROM pot
上面给出了标题中提到的错误。我知道我们不能用这种子查询选择两列。 我试图通过LEFT OUTER JOIN但无法让它工作。
SELECT id, id_user,
IFNULL( SUM(payment.amount), 0 ) AS collectedA,
IFNULL( SUM(payment.commission), 0 ) AS commission
FROM pot LEFT OUTER JOIN payment ON payment.id_pot = pot.id AND payment.stat = 1
但这给了我奇怪的结果......
答案 0 :(得分:2)
您必须LEFT JOIN
到已聚合的派生表,如下所示:
SELECT id, id_user, collectedA, commission
FROM pot
LEFT JOIN (
SELECT id_pot,
IFNULL( SUM(amount), 0 ) AS collectedA,
IFNULL( SUM(commission), 0 ) AS commission
FROM payment
WHERE stat = 1
GROUP BY id_pot
) AS pay pay.id_pot = pot.id
子查询中执行的GROUP BY
可确保您每pot.id
只能获得一条记录。
答案 1 :(得分:1)
您的LEFT JOIN
是正确的,但您忘记使用GROUP BY
。
SELECT pot.id, id_user,
IFNULL( SUM(payment.amount), 0 ) AS collectedA,
IFNULL( SUM(payment.commission), 0 ) AS commission
FROM pot
LEFT OUTER JOIN payment ON payment.id_pot = pot.id AND payment.stat = 1
GROUP BY pot.id
如果您需要WHERE
子句来仅选择部分花盆,请将其放在LEFT OUTER JOIN
之后。
SELECT pot.id, id_user,
IFNULL( SUM(payment.amount), 0 ) AS collectedA,
IFNULL( SUM(payment.commission), 0 ) AS commission
FROM pot
LEFT OUTER JOIN payment ON payment.id_pot = pot.id AND payment.stat = 1
WHERE ...
GROUP BY pot.id
答案 2 :(得分:1)
最有效的方法可能是两个子查询,特别是如果你想在pot
表上有过滤器:
select pot.id, pot.id_user,
(select sum(pay.amount)
from payment pay
where pay.id_pot = pot.id and pay.stat = 1
) as amount,
(select sum(pay.commission)
from payment pay
where pay.id_pot = pot.id and pay.stat = 1
) as commission
from pot;
为了有效地工作,您需要payment(id_pot, stat, amount, commission)
上的索引。这是两个查询的覆盖索引(意味着所有列都在索引中。
这似乎违反直觉,这更快,但它不需要全局聚合 - 所有聚合都可以使用索引扫描来处理。这通常更快。此外,pot
上的任何其他过滤器都会减少payment
表的工作量。