Mysql 查询 - 操作数应包含 1 列

Mysql query - Operand should contain 1 column

我在这里讨论了几个话题,但我无法让它工作。对于每个 "pot" 我想获得与此底池相关的付款次数以及全部佣金(所有付款佣金的总和)。

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

上面给出了标题中提到的错误。我知道我们不能使用这种子查询 select 两列。 我尝试通过 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

但这给了我奇怪的结果...

您必须 LEFT JOIN 已经聚合的 派生的 table,像这样:

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.

您将得到 恰好一条记录

你的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子句来select只有一些盆,把它放在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

最有效的方法可能是两个子查询,特别是如果你想在 pot table:

上使用过滤器
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 table.

上的工作需要