预期结果不是来自 mysql INNER JOIN
expecting result is not coming from mysql INNER JOIN
我有以下两个 table:
table: loan
--------------------------------------------------------
id | advance_id | loan_amount | deposit_amount | date
--------------------------------------------------------
1 | 22556678 | 5000 | 0 | 2015-02-06
--------------------------------------------------------
table: advance
--------------------------------------------------------
id | advance_id | advance_amount | purpose | date
--------------------------------------------------------
1 | 22556678 | 20000 | purchase | 2015-01-30
2 | 22556678 | 10000 | purchase | 2015-01-31
--------------------------------------------------------
我的代码是:
SELECT a.advance_id, sum(a.advance_amount) as adv_amount, a.purpose, a.date, sum(l.loan_amount) as loan_amount FROM advance as a INNER JOIN loan as l ON a.advance_id=l.advance_id GROUP BY a.advance_id HAVING sum(l.loan_amount)-sum(l.deposit_amount)>0
说明:
table 'advance' 是预付款的 table,table 'loan' 是贷款帐户的 table。出于同一目的(此处用于购买产品),可以多次预付款。每个预付款都由一个预付款 ID 标识。由于两次预付款的目的相同(此处用于购买产品),因此它们将具有相同的 advance_id。另一方面,贷款是针对任何预付款的。也可以针对同一预付款进行多次贷款。如果要偿还任何贷款,它将被插入 deposit_amount 列中 advance_id。
在loan_page.php中,仅当任何贷款为unpaid/unadjusted时才会显示贷款。为了识别它,我必须通过以下代码根据相同的预付款 ID 计算贷款和存款列:
GROUP BY a.advance_id HAVING sum(l.loan_amount)-sum(l.deposit_amount)>0
然后如果有任何未偿还的贷款,我必须确定每笔贷款有多少 advance_id。所以我还必须 SELECT 以下内容:
sum(l.loan_amount)
我获取的输出将是:
echo 'Total loan Amount: '.$row['loan_amount'].'<br />';
echo 'Advance ID: '.$row['advance_id'].'<br />';
echo 'Advance Amount: '.$row['adv_amount'].'<br />';
echo 'Purpose of Advance: '.$row['purpose'];
上面的代码运行良好,除了总贷款金额是双倍的(在本例中为 10000),尽管它将是 5000。我认为我的 mysql 的 GROUP BY 或 HAVING 子句有错误查询。
请告诉我,如何更正代码,使 sum(l.loan_amount) 在这种情况下为 5000,而不是 10000。
您想使用 union all
而不是 join
将表格放在一起。或者,或者,在连接之前聚合。
这里是 union all
版本:
SELECT advance_id,
sum(advance_amount) as adv_amount,
max(purpose) as purpose,
min(date) as date,
sum(loan_amount) as loan_amount
FROM ((SELECT a.advance_id,
a.advance_amount,
a.purpose,
a.date,
NULL as loan_amount,
NULL as deposit_amount
FROM advance
) UNION ALL
(SELECT l.advance_id, NULL, NULL, l.date, loan_amount, deposit_amount
FROM loan l
)
) al
GROUP BY advance_id
HAVING sum(loan_amount) - sum(deposit_amount) > 0;
loan_amount 是 double 的原因是因为您正在使用 advance_id 在 table 之间进行内部联接。由于 advance_id 在 advance_table 中出现了两次,因此贷款行将出现两次。在视觉上,连接给你这样的东西:
| advance | loan |
| 1 | 1 |
| 2 | 1 |
因此,当您在 l.loan_amount 上执行聚合时,它将被计算两次。要解决此问题,我会单独对每个 table 进行聚合,然后将它们连接在一起。例如,只需从贷款 table 中单独获取 advance_id 和 SUM(loan_amount),如下所示:
SELECT advance_id, SUM(loan_amount)
FROM loan
GROUP BY advance_id;
我注意到您原来的 HAVING
子句检查 loan_amount - deposit_amount,您可以在上面的查询中执行该条件:
SELECT advance_id, SUM(loan_amount) AS totalLoan
FROM loan
GROUP BY advance_id
HAVING SUM(loan_amount) - SUM(deposit_amount) > 0;
接下来,自己在预先table中进行必要的聚合,像这样:
SELECT advance_id, SUM(advance_amount) AS totalAdvance
FROM advance
GROUP BY advance_id;
然后,我将加入这两个 tables 以获得您需要的值:
SELECT t1.advance_id, t1.totalAdvance, t2.totalLoan
FROM(
SELECT advance_id, SUM(advance_amount) AS totalAdvance
FROM advance
GROUP BY advance_id) t1
JOIN(
SELECT advance_id, SUM(loan_amount) AS totalLoan
FROM loan
GROUP BY advance_id
HAVING SUM(loan_amount) - SUM(deposit_amount) > 0) t2 ON t2.advance_id = t1.advance_id;
注意
我没有包括目的或日期,因为它们在预付款中不一致 table。您将不得不考虑每种情况。如果两行的目的不同怎么办?日期不同,那么您需要返回哪个日期(如果有)?一旦你知道了,你就可以将它们添加到这个查询中,可能是在 'advance' 子查询中。
这是一个 SQL Fiddle 示例。
我有以下两个 table:
table: loan
--------------------------------------------------------
id | advance_id | loan_amount | deposit_amount | date
--------------------------------------------------------
1 | 22556678 | 5000 | 0 | 2015-02-06
--------------------------------------------------------
table: advance
--------------------------------------------------------
id | advance_id | advance_amount | purpose | date
--------------------------------------------------------
1 | 22556678 | 20000 | purchase | 2015-01-30
2 | 22556678 | 10000 | purchase | 2015-01-31
--------------------------------------------------------
我的代码是:
SELECT a.advance_id, sum(a.advance_amount) as adv_amount, a.purpose, a.date, sum(l.loan_amount) as loan_amount FROM advance as a INNER JOIN loan as l ON a.advance_id=l.advance_id GROUP BY a.advance_id HAVING sum(l.loan_amount)-sum(l.deposit_amount)>0
说明: table 'advance' 是预付款的 table,table 'loan' 是贷款帐户的 table。出于同一目的(此处用于购买产品),可以多次预付款。每个预付款都由一个预付款 ID 标识。由于两次预付款的目的相同(此处用于购买产品),因此它们将具有相同的 advance_id。另一方面,贷款是针对任何预付款的。也可以针对同一预付款进行多次贷款。如果要偿还任何贷款,它将被插入 deposit_amount 列中 advance_id。
在loan_page.php中,仅当任何贷款为unpaid/unadjusted时才会显示贷款。为了识别它,我必须通过以下代码根据相同的预付款 ID 计算贷款和存款列:
GROUP BY a.advance_id HAVING sum(l.loan_amount)-sum(l.deposit_amount)>0
然后如果有任何未偿还的贷款,我必须确定每笔贷款有多少 advance_id。所以我还必须 SELECT 以下内容:
sum(l.loan_amount)
我获取的输出将是:
echo 'Total loan Amount: '.$row['loan_amount'].'<br />';
echo 'Advance ID: '.$row['advance_id'].'<br />';
echo 'Advance Amount: '.$row['adv_amount'].'<br />';
echo 'Purpose of Advance: '.$row['purpose'];
上面的代码运行良好,除了总贷款金额是双倍的(在本例中为 10000),尽管它将是 5000。我认为我的 mysql 的 GROUP BY 或 HAVING 子句有错误查询。
请告诉我,如何更正代码,使 sum(l.loan_amount) 在这种情况下为 5000,而不是 10000。
您想使用 union all
而不是 join
将表格放在一起。或者,或者,在连接之前聚合。
这里是 union all
版本:
SELECT advance_id,
sum(advance_amount) as adv_amount,
max(purpose) as purpose,
min(date) as date,
sum(loan_amount) as loan_amount
FROM ((SELECT a.advance_id,
a.advance_amount,
a.purpose,
a.date,
NULL as loan_amount,
NULL as deposit_amount
FROM advance
) UNION ALL
(SELECT l.advance_id, NULL, NULL, l.date, loan_amount, deposit_amount
FROM loan l
)
) al
GROUP BY advance_id
HAVING sum(loan_amount) - sum(deposit_amount) > 0;
loan_amount 是 double 的原因是因为您正在使用 advance_id 在 table 之间进行内部联接。由于 advance_id 在 advance_table 中出现了两次,因此贷款行将出现两次。在视觉上,连接给你这样的东西:
| advance | loan |
| 1 | 1 |
| 2 | 1 |
因此,当您在 l.loan_amount 上执行聚合时,它将被计算两次。要解决此问题,我会单独对每个 table 进行聚合,然后将它们连接在一起。例如,只需从贷款 table 中单独获取 advance_id 和 SUM(loan_amount),如下所示:
SELECT advance_id, SUM(loan_amount)
FROM loan
GROUP BY advance_id;
我注意到您原来的 HAVING
子句检查 loan_amount - deposit_amount,您可以在上面的查询中执行该条件:
SELECT advance_id, SUM(loan_amount) AS totalLoan
FROM loan
GROUP BY advance_id
HAVING SUM(loan_amount) - SUM(deposit_amount) > 0;
接下来,自己在预先table中进行必要的聚合,像这样:
SELECT advance_id, SUM(advance_amount) AS totalAdvance
FROM advance
GROUP BY advance_id;
然后,我将加入这两个 tables 以获得您需要的值:
SELECT t1.advance_id, t1.totalAdvance, t2.totalLoan
FROM(
SELECT advance_id, SUM(advance_amount) AS totalAdvance
FROM advance
GROUP BY advance_id) t1
JOIN(
SELECT advance_id, SUM(loan_amount) AS totalLoan
FROM loan
GROUP BY advance_id
HAVING SUM(loan_amount) - SUM(deposit_amount) > 0) t2 ON t2.advance_id = t1.advance_id;
注意
我没有包括目的或日期,因为它们在预付款中不一致 table。您将不得不考虑每种情况。如果两行的目的不同怎么办?日期不同,那么您需要返回哪个日期(如果有)?一旦你知道了,你就可以将它们添加到这个查询中,可能是在 'advance' 子查询中。
这是一个 SQL Fiddle 示例。