在SUM()查询后获取错误的值

时间:2017-10-06 20:14:09

标签: sql sql-server

我正在执行以下查询:

SELECT 
                    MAX(table1.id) as id, 
                    clients.Username as account, 
                    table1.clientid, 
                    SUM(table1.symbols) as symbols, 
                    SUM(table1.tickets) as tickets, 
                    SUM(table1.cash) as cash, 
                    (SUM(CASE WHEN table2.memo = 'Withdraw' THEN amount ELSE 0 END)) AS withdraw,
                    (SUM(CASE WHEN table2.memo = 'Depos' THEN amount ELSE 0 END)) AS depos,
                FROM 
                    table1 
                LEFT JOIN 
                    (                       
                        clients 
                            LEFT JOIN 
                            table2 
                            ON 
                        clients.Fidx = table2.clientid 
                        AND 
                        table2.date >= '01-09-2016' 
                 AND 
                    table2.date <= '01-09-2017'

                    )                                                                              
                ON 
                    clients.Fidx = table1.clientid 
                WHERE 
                    table1.tradedate >= '01-09-2016' 
                 AND 
                    table1.tradedate <= '01-09-2017'
                GROUP BY 
                    table1.clientid, clients.Username, table2.clientid 
                ORDER BY 
                    clients.Username;

我希望得到一个由三个表组合而成的简单结果表:

+---------+--------+---------+
| account |withdraw|  depos  |
+---------+--------+---------+
|   adaf  |   300  |      0  |
|   rich  |   1000 |    355  |
|   call  |     0  |     45  |
|   alen  |     0  |      0  |
|  courney|     0  |     106 |
|  warren |     0  |      0  |
+---------+--------+---------+

有什么问题? - 我在结果表中得到了错误的值。完全在withdrawdepos。它们的数量比应有的数量多4倍。例如,对于某些客户端SUM(depos)应为500,但在我的结果表中,此值为2000.我猜,问题出现在GROUP BY方法中,因为当我执行以下查询时,结果看起来还不错:

SELECT clientid, SUM(case when memo = 'Withdraw' then amount else 0 end) as withdraw, SUM(case when memo = 'Depos' then amount else 0 end) as depos
 from clients 
 LEFT JOIN 
 table2 
 ON
 clients.Fidx = table2.clientid
 WHERE table2.date >= '01-09-2016' and table2.date<='01-09-2017' GROUP BY clientid ORDER BY clientid;

这种错误结果可能是什么原因?伙计们,我很麻烦,需要你的帮助。

2 个答案:

答案 0 :(得分:2)

你几乎用底层查询回答了这个问题。您需要在派生表或子查询中对连接进行求和,就像在底部查询中一样。这将确保您加入多对一关系,而不是多对多关系,这必须导致您当前的重复(或者&#39;倍增&#39;总和)。

SELECT 
                    MAX(table1.id) as id, 
                    clients.Username as account, 
                    table1.clientid, 
                    SUM(table1.symbols) as symbols, 
                    SUM(table1.tickets) as tickets, 
                    SUM(table1.cash) as cash, 
                    withdraw,
                    depos,
                FROM 
                    table1 
                LEFT JOIN 
                    (SELECT clientid, 
                            SUM(case when memo = 'Withdraw' then amount else 0 end) as withdraw, 
                            SUM(case when memo = 'Depos' then amount else 0 end) as depos
                     FROM clients 
                     LEFT JOIN table2 ON clients.Fidx = table2.clientid
                     AND table2.date >= '01-09-2016' 
                     AND table2.date<='01-09-2017' 
                     GROUP BY clientid) clients                                                                        
                ON 
                    clients.clientID = table1.clientid 
                WHERE 
                    table1.tradedate >= '01-09-2016' 
                 AND 
                    table1.tradedate <= '01-09-2017'
                GROUP BY 
                    table1.clientid, clients.Username, table2.clientid, clients.depos, clients.withdraw
                ORDER BY 
                    clients.Username;

进一步的例子:

Table1
id | someInfo
1  |  a
1  |  b
1  |  c

Table2
id | value
1  |   5
1  |   10

此查询:

SELECT t1.id, SUM(t2.Value)
FROM table1 t1
JOIN table2 t2 on t1.id = t2.id --This will be many-to-many
GROUP BY t1.id

会导致这个:

Results
id | value
1  |  45   --sum of 45 because the `table2` values are triplicated from the join

此查询的位置:

SELECT DISTINCT t1.id, Value
FROM table1 t1
JOIN (SELECT id, SUM(Value) value
      FROM table2
      GROUP BY id) t2 on t1.id = t2.id --This will be many-to-one

会导致这个:

Results
id | value
1  |  15   --sum of 15 because the `table2` values are not triplicated from the join

答案 1 :(得分:1)

加入前聚合:

select
  t1.id, 
  c.Username as account, 
  c.clientid, 
  t1.symbols, 
  t1.tickets, 
  t1.cash, 
  coalesce(t2.withdraw, 0) as withdraw,
  coalesce(t2.depos, 0) as depos
from clients c
join
(
  select 
    clientid,
    max(id) as id,
    sum(symbols) as symbols, 
    sum(tickets) as tickets, 
    sum(cash) as cash
  from table1
  where date >= '20160901' and date <= '20170901'
  group by clientid
) t1 on t1.clientid = c.fidx
left join
(
  select 
    clientid,
    sum(case when memo = 'Withdraw' then amount end) as withdraw,
    sum(case when memo = 'Depos' then amount end) as depos
  from table2
  where date >= '20160901' and date <= '20170901'
  group by clientid
) t2 on t2.clientid = c.fidx;