SELECT User.username,
IFNULL(SUM(credit) - SUM(debit), 0) AS total,
( SELECT SUM(Bid.credit) - SUM(Bid.debit) AS freebids
FROM users AS User
LEFT
JOIN bids AS Bid
ON Bid.user_id = User.id
WHERE Bid.type = 2
) AS FreeBids,
( SELECT SUM(Bid.credit) - SUM(Bid.debit) AS Normalbids
FROM users AS User
LEFT
JOIN bids AS Bid
ON Bid.user_id = User.id
WHERE Bid.type = 0
OR Bid.type = 1
) AS NormalBids
FROM users AS User
LEFT
JOIN bids AS Bid
ON Bid.user_id = User.id
GROUP
BY User.id
这是我的示例表: 对于用户
id username
1 user1
2 user2
3 user3
4 user4
出价
id user_id debit credit type
1 1 0 10 0
2 1 1 5 2
3 1 1 0 2
4 3 0 10 0
6 2 0 10 0
7 4 1 10 0
8 4 1 0 1
但我在显示子查询时遇到问题(Freebids和Normalbids)都具有相同的值,这里是示例显示:
username total FreeBids NormalBids
user1 10 12809 965
user2 20 12809 965
user3 9 12809 965
user4 0 12809 965
我无法弄清楚我在查询中的位置。 有什么建议可以解决我的问题吗? 谢谢你的帮助。
答案 0 :(得分:2)
所有相同值出现的原因是外部查询中的users
表与内部查询中的users
表之间没有区别。它们都有相同的别名。您必须通过为其分配不同的别名(例如users
)来区分外部users
表或内部u
表,以便子查询知道要为外部值引用哪个表:
... FROM users AS u ...
话虽如此,使用像这样的子查询是非常低效的,因为它们需要在users
表中的 每个 行执行(我们& #39;重新讨论需要加入和过滤的整个表,与用户x2一样多次。
使用条件聚合可以更有效地重写您的查询:
SELECT
a.username,
IFNULL(SUM(b.credit) - SUM(b.debit), 0) AS total,
SUM(IF(b.type = 2, b.credit, 0)) - SUM(IF(b.type = 2, b.debit, 0)) AS freebids,
SUM(IF(b.type IN (0,1), b.credit, 0)) - SUM(IF(b.type IN (0,1), b.debit, 0)) AS normalbids
FROM users a
LEFT JOIN bids b ON a.id = b.user_id
GROUP BY a.id, a.username
其中基本上说:仅在信用卡/借记卡合并时,如果类型为x
值,则可以使用SUM / COUNT / AVG /等。在任何情况下你只想使用一个表连接。
答案 1 :(得分:0)
子查询和连接的组合实际上没有意义:对于外部查询的每一行,每个子查询将返回相同的多行行,而不是返回与外部行对应的正确单个值查询。
有几种方法可以做你想要的,但我认为最简单的方法是完全消除连接,并使用相关的子查询:
SELECT User.username,
( SELECT IFNULL(SUM(credit) - SUM(debit), 0)
FROM bids AS Bid
WHERE Bid.user_id = User.id
) AS total,
( SELECT IFNULL(SUM(credit) - SUM(debit), 0)
FROM bids AS Bid
WHERE Bid.user_id = User.id
AND Bid.type = 2
) AS FreeBids,
( SELECT IFNULL(SUM(credit) - SUM(debit), 0)
FROM bids AS Bid
WHERE Bid.user_id = User.id
AND Bid.type IN (0, 1)
) AS NormalBids
FROM users AS User
;
每个子查询都引用外部查询中的User
记录,保持一切井井有条。