SQL Query SUM问题

时间:2013-11-29 09:25:46

标签: sql sum

我正在编写一个SQL查询,我希望列出并计算一些数据,每一件事看起来都能正常工作但我遇到的唯一问题是当我在给定列中的SUM值时,最终结果是总计但是我希望这个总数只能是10月的一个月。

方案如下:我需要计算10月份客户的存款总额,其他信息仅适用于总和问题。

SQL:

SELECT customers.id                                      AS 'Customer ID', 
       customers.firstname                               AS 
       'Customer First Name', 
       customers.lastname                                AS 'Customer Last Name' 
       , 
       users.firstname                                   AS 
       'Employee First Name', 
       users.lastname                                    AS 'Employee Last Name' 
       , 
       positions.currency                                AS 'Currency', 
       Sum(customer_deposits.amount)                     AS 'Total Deposits', 
       Sum(positions.status)                             AS 'Total Bets', 
       Sum(customer_total_statistics.totalbonusdeposits) AS 'Total Bonuses', 
       positions.date                                    AS 'Date' 
FROM   customers 
       LEFT JOIN customer_deposits 
              ON customers.id = customer_deposits.customerid 
       LEFT JOIN users 
              ON customers.employeeinchargeid = users.id 
       LEFT JOIN positions 
              ON customers.id = positions.customerid 
       LEFT JOIN customer_total_statistics 
              ON customers.id = customer_total_statistics.customerid 
WHERE  customer_deposits.status = 'approved' 
       AND positions.status = 'won' 
       AND positions.date BETWEEN '2013-10-01' AND '2013-11-01' 
       AND customers.isdemo = '0' 
GROUP  BY customers.id 
ORDER  BY customers.id 

2 个答案:

答案 0 :(得分:0)

嗯,你根本不过滤你的customer_deposits,所以对customer_deposits.amount的总和当然会给你所有存款的总和。您还必须添加另一个按日期过滤customer_deposits的位置,而不仅仅是位置。

答案 1 :(得分:0)

看起来您有多个1-n关系,因此您的联接正在创建笛卡尔积。因此,如果您的客户有2个存款和2个职位:

Positions                       customer_deposits

CustomerID | Amount             CustomerID | Amount         
1          |  10                    1      |  30
1          |  20                    1      |  40

当你这样做时加入:

SELECT  c.ID, cd.Amount AS DepositAmount, p.Amount AS PositionAmount
FROM    Customers c
        INNER JOIN customer_deposits cd
            ON c.ID = cd.CustomerID
        INNER JOIN Positions p
            ON c.ID = p.CustomerID

您最终得到4行,包含存款金额和头寸金额的所有组合:

ID  DepositAmount PositionAmount
1       10              30
1       10              40
1       20              30
1       20              40

因此,如果你总结一下,你最终会得到不正确的总和,因为行是重复的。您需要将SUM移动到子查询:

SELECT customers.id             AS 'Customer ID', 
       customers.firstname      AS 'Customer First Name', 
       customers.lastname       AS 'Customer Last Name',
       users.firstname          AS 'Employee First Name', 
       users.lastname           AS 'Employee Last Name',
       positions.currency       AS 'Currency', 
       cd.amount                AS 'Total Deposits', 
       P.status                 AS 'Total Bets', 
       cs.totalbonusdeposits    AS 'Total Bonuses', 
       positions.date           AS 'Date' 
FROM   customers 
       INNER JOIN 
       (    SELECT  CustomerID, SUM(Amount) AS Amount
            FROM    customer_deposits 
            WHERE   customer_deposits.status = 'approved' 
            GROUP BY CustomerID
        ) cd
              ON customers.id = cd.customerid 
       LEFT JOIN users 
              ON customers.employeeinchargeid = users.id 
       INNER JOIN 
       (    SELECT  CustomerID, Date, SUM(Status) AS Status
            FROM    positions 
            WHERE   positions.status = 'won' 
            AND     positions.date BETWEEN '2013-10-01' AND '2013-11-01' 
            GROUP BY CustomerID, Date
        ) P
            ON customers.id = positions.customerid 
       LEFT JOIN 
       (    SELECT  CustomerID, SUM(totalbonusdeposits) AS totalbonusdeposits
            FROM    customer_total_statistics 
            GROUP BY CustomerID
        ) cs
            ON customers.id = customer_total_statistics.customerid 
WHERE   customers.isdemo = '0';

注意,您已在左侧连接表的where子句中使用了字段,这些字段有效地将它们转换为内部连接,例如

positions.status = 'won'

如果位置不匹配,状态将为NULLNULL = 'won'计算为NULL(不是真),因此它将排除{{1}中没有匹配的所有行}。因此我将你的LEFT JOIN改为INNER。