如何修复mysql子查询显示

时间:2012-07-12 02:24:41

标签: php mysql

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

我无法弄清楚我在查询中的位置。 有什么建议可以解决我的问题吗? 谢谢你的帮助。

2 个答案:

答案 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 /等。在任何情况下你只想使用一个表连接。


SQL-Fiddle Demo

答案 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记录,保持一切井井有条。