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を合計し、SUM/COUNT/AVG/etc を実行できます。任意の条件で、1 つのテーブル結合で作業するだけです。


SQL フィドルのデモ

于 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 に答える