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.
上的工作需要
我在这里讨论了几个话题,但我无法让它工作。对于每个 "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.