mysql left join 将行放在一起

标签 mysql join

我有 3 个表:发票、人员和付款。 我想要一份发票 list ,其中包含客户姓名(来自个人)以及付款总额和付款日期(来自付款)。

首先我发表这些声明

SELECT V.id, V.datum, V.amount, P.name AS 'client', 
(SELECT SUM(B.amount) FROM payement AS B WHERE B.invoiceId = V.id) AS 'payed',
(SELECT GROUP_CONCAT(B.datum SEPARATOR ',') FROM payement AS B WHERE B.invoiceId = V.id) AS 'date payement'
FROM invoice AS V 
JOIN person AS P ON (V.clientId = P.id)
WHERE YEAR(V.datum) = '2015' 
ORDER BY V.datum;

这给出了我想要的(例如,9 月 4 日一笔 1000 笔交易,9 月 10 日一笔 2400 笔交易),但当我有大量发票时,工作速度非常慢。

+------+-----------+--------+--------+-------+---------------------+
| id   |  datum    | amount | client | payed | date payement       |
+------+-----------+--------+--------+-------+---------------------+
| 75   |2015-09-10 | 3400   |Sommers | 3400  |2015-09-04,2015-09-10|
+------+-----------+--------+--------+-------+---------------------+

所以我尝试了另一种说法。

SELECT V.id, V.datum, V.amount, P.name AS 'client', B.amount AS 'payed', B.datum 'date payement'
FROM invoice AS V 
JOIN person AS P ON (V.clientId = P.id)
LEFT JOIN payement AS B ON B.invoiceId = V.id
WHERE YEAR(V.datum) = '2015' 
ORDER BY V.datum;

但是当通过 2 笔交易支付时,这给了我 1 张发票 2 行。 我可以用 SQL 解决它,还是在我的应用程序(Java 中)中解决它更好?

最佳答案

当发票已分两次付款时,您希望使用哪些详细信息?第一次付款还是第二次付款?

假设您想要总付款金额和最晚付款日期:-

SELECT V.id, 
        V.datum, 
        V.amount, 
        P.name AS 'client', 
        SUM(B.amount) AS 'payed', 
        MAX(B.datum) AS 'date payement'
FROM invoice AS V 
JOIN person AS P ON (V.clientId = P.id)
LEFT OUTER JOIN payement AS B ON B.invoiceId = V.id
WHERE YEAR(V.datum) = '2015' 
GROUP BY V.id, 
        V.datum, 
        V.amount,
        P.name
ORDER BY V.datum

我不使用 phpmyadmin。

mysql> EXPLAIN SELECT V.factuurnr, 
    ->         V.datum, 
    ->         V.somexcl, 
    ->         P.naam AS 'client', 
    ->         SUM(B.bedrag) AS 'payed', 
    ->         GROUP_CONCAT(DATE_FORMAT(B.datum,'%d/%m/%y') SEPARATOR ',') AS 'date payement'
    -> FROM verkoop AS V 
    -> JOIN persoon AS P ON (V.klantId = P.id)
    -> LEFT JOIN betaling AS B ON B.docId = V.id
    -> WHERE YEAR(V.datum) = '2015' and month(V.datum)=9
    -> GROUP BY V.factuurnr, 
    ->         V.datum, 
    ->         V.somexcl,
    ->         P.naam
    -> ORDER BY factuurnr;
+----+-------------+-------+--------+---------------+---------+---------+----------------+------+----------------------------------------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref            | rows | Extra                                        |
+----+-------------+-------+--------+---------------+---------+---------+----------------+------+----------------------------------------------+
|  1 | SIMPLE      | V     | ALL    | NULL          | NULL    | NULL    | NULL           | 1576 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | P     | eq_ref | PRIMARY       | PRIMARY | 4       | meta.V.klantId |    1 | Using where                                  |
|  1 | SIMPLE      | B     | ALL    | NULL          | NULL    | NULL    | NULL           | 3291 |                                              |
+----+-------------+-------+--------+---------------+---------+---------+----------------+------+----------------------------------------------+
3 rows in set (0.00 sec)

关于mysql left join 将行放在一起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33284896/

相关文章:

php - 如何将以逗号分隔的多个值输入到表中?

php - 为什么我的动态删除不起作用?

mysql - 在 MySQL 中对大表进行更新查询

mysql - 如何检查一个字段中的字符串是否存在于逗号分隔字段的每个元素中

php - 获取 PHP/MySql 中约束错误的键名?

mysql - 表 (A) 与其自身的自然连接

mysql - 使用 IN 运算符进行 JOIN 查询

mysql - 在Where 子句中使用/多个名称/值对进行SQL 查询

mysql - 使用 MYSQL 连接两个查询并处理日期

MySQL根据场景适配JOIN