MySQL与子查询的左连接使用不同的排序生成不同的结果

MySQL与子查询的左连接使用不同的排序生成不同的结果,mysql,join,group-by,left-join,Mysql,Join,Group By,Left Join,我有两个表:发票和付款交易。其中paymentTransactions表包含发票的付款交易记录-可能有多个记录 表:发票: invoiceId, customerId, amount 表:支付交易: paymentTransactionId, invoiceId, status paymentTransactionId, invoiceId, status 305 3062 2 306 3062

我有两个表:发票付款交易。其中paymentTransactions表包含发票的付款交易记录-可能有多个记录

表:发票:

invoiceId, customerId, amount
表:支付交易:

paymentTransactionId, invoiceId, status
paymentTransactionId, invoiceId, status
305                     3062        2
306                     3062        1
要求是获得发票以及最新的付款交易日志

我尝试了下面的查询,但它返回的结果不同,排序也不同

SELECT i.invoiceId,recentTrans.maxTransId,  cts.status as recentStatus  FROM invoices i LEFT JOIN  (SELECT MAX(paymentTransactionId) AS maxTransId, invoiceId FROM paymentTransactions GROUP BY invoiceId) recentTrans      ON recentTrans.invoiceId = i.invoiceId  LEFT JOIN paymentTransactions cts ON cts.paymentTransactionId = recentTrans.maxTransId AND cts.invoiceId = recentTrans.invoiceId WHERE i.invoiceId IN(130623, 3062)  GROUP BY i.invoiceId ORDER BY `invoiceId` desc;

实际上,invoiceId:130623没有支付交易,但recentStatus返回为1。它应该返回NULL

数据:

发票:

invoiceId, customerId, amount
invoiceId  customerId amount
3062          1         40
130623        2         60
付款交易:

paymentTransactionId, invoiceId, status
paymentTransactionId, invoiceId, status
305                     3062        2
306                     3062        1
感谢所有答复


谢谢

您得到了意外的结果,因为在
选择
列表中,有未聚合的列未包含在
分组依据
子句中。

但是您不需要
GROUPBY
子句:

SELECT i.invoiceId, cts.paymentTransactionId maxTransId, cts.status as recentStatus  
FROM invoices i 
LEFT JOIN  (
  SELECT MAX(paymentTransactionId) AS maxTransId, invoiceId 
  FROM paymentTransactions 
  GROUP BY invoiceId
) recentTrans ON recentTrans.invoiceId = i.invoiceId  
LEFT JOIN paymentTransactions cts 
ON cts.paymentTransactionId = recentTrans.maxTransId AND cts.invoiceId = i.invoiceId 
WHERE i.invoiceId IN (130623, 3062)  
ORDER BY i.invoiceId ASC;
或使用相关子查询:

SELECT i.invoiceId, pt.paymentTransactionId maxTransId, pt.status as recentStatus  
FROM invoices i LEFT JOIN paymentTransactions pt 
ON pt.invoiceId = i.invoiceId 
AND pt.paymentTransactionId = (
  SELECT MAX(paymentTransactionId)
  FROM paymentTransactions
  WHERE invoiceId = i.invoiceId  
)
WHERE i.invoiceId IN (130623, 3062)  
ORDER BY i.invoiceId ASC;
或者,如果您的MySql版本是8.0+,请使用带有
行号()的CTE
窗口函数:

WITH pt AS (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY invoiceId ORDER BY paymentTransactionId DESC) rn
  FROM paymentTransactions
)
SELECT i.invoiceId, pt.paymentTransactionId maxTransId, pt.status as recentStatus 
FROM invoices i LEFT JOIN pt
ON pt.invoiceId = i.invoiceId AND pt.rn = 1 
WHERE i.invoiceId IN (130623, 3062)  
ORDER BY i.invoiceId ASC;
请参阅。


你能添加样本数据吗?添加了样本数据。请刷新您的查询没有生成您看到的结果,并且您有一个组,如果仅设置了“全组”或“组”的话,该组将无效,我无法重现您的问题这是当您选择不出现在GROUP BY子句中的非聚合列时发生的情况。@P.Salmon但唯一的_full_GROUP_BY选项是禁用的。您的第二个解决方案是,我在GROUP BY子句中添加了字段:paymentTransactionId以及invoiceId。非常感谢。