用左连接的两个表的mysql查询 - 得到错误的结果

时间:2016-06-02 13:17:24

标签: php mysql

我正在使用左连接加入两个表来获得总和结果,但它给出了错误的结果。这是我的

table1
    | id | event | currency | amount |
    |----|-------|----------|--------|
    | 1  | HSA   | USD      | 2000   |
    | 2  | DMME  | USD      | 3000   |
    | 3  | HSI   | INR      | 1500   |
    | 4  | HSI   | INR      | 1500   | 

表2

| id | table1_id | rcvamount | adjamount |
|----|-----------|-----------|-----------|
| 1  | 1         | 1980      | 20        |
| 2  | 2         | 1000      | 180       |
| 3  | 2         | 1500      | 20        |
| 4  | 4         | 1487      | 13        |

这是我的查询

SELECT
T1.event,T1.currency,
SUM(T1.total) AS Totalvalue,

SUM(T1.received) AS Received, 
(T1.bal) AS balance
FROM (SELECT
      table1.id,
      table1.amount AS total,

      SUM(table2.rcvamount+table2.adjamount) AS received,
      ((table1.amount)- sum(table2.rcvamount+table2.adjamount)) AS bal,
      table1.event,  
      table1.currency
      FROM table1 LEFT JOIN table2 ON table1.id=table2.table1_id 
     group by table1.id)T1
      Group By T1.event,T1.currency

但是,当我运行此查询时给出错误的结果如下所示。当涉及到名为HSI的第三个事件时,表2中的id号为3没有任何行。结果应按事件和货币分组。

| event | currency | Totalvalue | Received | balance |
|-------|----------|------------|----------|---------|
| DMME  | USD      | 3000       | 2700     | 300     |
| HSA   | USD      | 2000       | 2000     | 0       |
| HSI   | INR      | 3000       | 1500     | NULL    |

但实际结果应如下

| event | currency | Totalvalue | Received | balance |
|-------|----------|------------|----------|---------|
| DMME  | USD      | 3000       | 2700     | 300     |
| HSA   | USD      | 2000       | 2000     | 0       |
| HSI   | INR      | 3000       | 1500     | 1500    |

我没有得到我的查询出错的地方。请帮我分类。谢谢。

2 个答案:

答案 0 :(得分:2)

您正在使用LEFT JOIN,因此您将拥有所有第一个表行,即使它们在第二个表中没有任何匹配所需的连接。

在第一个表中,id = 3在第二个表中没有匹配,因此您获得NULL结果。 (SELECT * FROM table2 WHERE table1_id =3将给出0结果)。

要避免使用INNER JOIN

SELECT T1.event, T1.currency, SUM( T1.total ) AS Totalvalue, 
       SUM( T1.received ) AS Received, ( T1.bal) AS balance
    FROM (
     SELECT table1.id, table1.amount AS total, 
     SUM( table2.rcvamount + table2.adjamount ) AS received, 
     ((table1.amount) - sum( table2.rcvamount + table2.adjamount ))AS bal,
     table1.event, table1.currency
     FROM table1
     INNER JOIN table2 ON table1.id = table2.table1_id
    GROUP BY table1.id
   )T1

 GROUP BY T1.event, T1.currency

更新:

试试这个,COALESCE()会将每个null转换为0

SELECT T1.event, T1.currency, SUM( T1.total ) AS Totalvalue, SUM( T1.received ) AS Received, (
T1.bal
) AS balance
FROM (

SELECT table1.id, table1.amount AS total, SUM( COALESCE( table2.rcvamount, 0 ) + COALESCE( table2.adjamount, 0 ) ) AS received, (
COALESCE( table1.amount, 0 ) - sum( COALESCE( table2.rcvamount, 0 ) + COALESCE( table2.adjamount, 0 ) )
) AS bal, table1.event, table1.currency
FROM table1
LEFT JOIN table2 ON table1.id = table2.table1_id
GROUP BY table1.id
)T1
GROUP BY T1.event, T1.currency

答案 1 :(得分:0)

它适合你

select tp.id,tp.event,tp.currency,
tp.totalvalue,
tr.received,
(tp.totalvalue - tr.received) AS balance
from  
(
select max(id)id,event,currency,amount,sum(amount)as totalvalue from t1
group by t1.event
)tp
inner join  
(
 select id,table1_id,rcvamount,adjamount,(sum(rcvamount) + sum(adjamount))as received
 from t2 
 group by table1_id
 order by t2.adjamount desc
)tr
 on tp.id = tr.id 
group by tp.event