1
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

我不知道我在查询中去哪儿了。有什么建议可以解决我的问题吗?感谢您的帮助。

4

2 回答 2

2

之所以出现所有相同的值,是因为users外部查询中的users表和内部查询中的表没有区别。他们都有相同的别名。您必须通过为其分配不同的别名(例如)来区分外部users表或内部表,以便子查询知道要为外部值引用哪个表:usersu

... FROM users AS u ...

话虽如此,使用这样的子查询效率非常低,因为它们需要对表中的每一行执行users(我们正在讨论整个表需要连接和过滤的次数与用户 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

基本上说:仅当类型为value时才对贷方/借方求和x,并且您可以求和/计数/平均/等。在任何情况下,您只想使用一个表连接。


SQL-Fiddle 演示

于 2012-07-12T02:44:17.430 回答
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外部查询中的记录,从而使所有内容井井有条。

于 2012-07-12T02:33:38.883 回答