mysql左连接将行放在一起

mysql左连接将行放在一起,mysql,join,Mysql,Join,我有三张表:发票、人员和付款。 我想有一个发票清单,上面有客户名称(来自个人)和付款总额以及付款日期(来自付款) 首先,我发表了这些声明 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

我有三张表:发票、人员和付款。 我想有一个发票清单,上面有客户名称(来自个人)和付款总额以及付款日期(来自付款)

首先,我发表了这些声明

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)

谢谢,这是可行的,但是它仍然很慢,但速度是我的第一个解决方案的两倍。作为“日期付款”,我不需要日期,而是不同日期的串联。因此我使用了:GROUP_CONCAT(B.datum)分隔符','),而不是MAX(B.datum)。索引可能需要调整以提高性能。此外,使用YEAR(V.datum)需要在每一行上使用一个函数,而不能使用索引,但是在'2015-01-01'和'2014-12-31'之间使用WHERE V.datum可能更快。据我所知,是'LEFT'连接需要时间。请发布表定义。还可以尝试对查询进行解释,然后发布。没有LEFT需要0.03秒,LEFT需要0.66秒。
但是我不会得到没有付款的发票。
如果我省略了LEFT,并且使用相同的语句进行联合,而没有JOIN payment,则需要0.08秒,但是我有多个副本(正如我所说,distinct不适用于1列)。