0

我有一张满是用户付款的桌子。每个用户可以进行多次付款。我希望为每个用户选择最新的付款。

SELECT DATE_FORMAT(FROM_UNIXTIME(MAX(p.date)), "%D %M %Y") as last_payment, p.user_id, p.amount, p.period, p.txn_id, u.name 
FROM payments as p
INNER JOIN users as u
ON u.id = p.user_id
GROUP BY p.user_id
ORDER BY p.date DESC

现在这似乎工作正常,该last_payment字段确实是用户最近一次付款的日期,唯一的问题是其他付款字段与用户上次付款相同p.txn_idp.amount不一定对应于同一行,而是来自以前的付款。

我如何确保当我选择它时,MAX(p.date)它也会从同一行中选择其他字段。

感谢帮助。

4

4 回答 4

1

您正在寻找分组最大值;最常见的方法是将付款表连接回分组结果:

SELECT   DATE_FORMAT(FROM_UNIXTIME(p.date), '%D %M %Y') AS last_payment,
         p.user_id, p.amount, p.period, p.txn_id, u.name
FROM     payments AS p NATURAL JOIN (
           SELECT   user_id, MAX(date) date
           FROM     payments
           GROUP BY user_id
         ) t JOIN users AS u ON u.id = p.user_id
ORDER BY p.date DESC

请注意,您的原始查询完全有效(并且没有引发错误)的唯一原因是因为MySQL 的非标准扩展GROUP BY

MySQL 扩展了 的使用,GROUP BY以便选择列表可以引用未在GROUP BY子句中命名的非聚合列。这意味着前面的查询在 MySQL 中是合法的。您可以使用此功能通过避免不必要的列排序和分组来获得更好的性能。但是,这主要在GROUP BY每个组中未命名的每个非聚合列中的所有值都相同时很有用。服务器可以自由地从每个组中选择任何值,因此除非它们相同,否则选择的值是不确定的。

于 2013-06-04T14:45:16.843 回答
0
SELECT DATE_FORMAT(p.date, "%D %M %Y") as last_payment, p.user_id, p.amount, p.period, p.txn_id, u.name 
FROM payments as p where 
INNER JOIN users as u
ON u.id = p.user_id
GROUP BY p.user_id having FROM_UNIXTIME(p.date)=FROM_UNIXTIME(MAX(p.date))
ORDER BY p.date DESC
于 2013-06-04T14:18:12.153 回答
0

尝试这样的事情

SELECT DATE_FORMAT(FROM_UNIXTIME(p.date), "%D %M %Y") as last_payment
       , p.user_id, p.amount, p.period, p.txn_id, u.name 
FROM payments p, users u
WHERE u.id = p.user_id 
  and exists (SELECT max(p1.date) from payments p1 
               where p1.user_id = p.user_id 
              having max(p1.date)=p.date 
               group by p.user_id,  p1.date )
ORDER BY p.date DESC
于 2013-06-04T14:15:45.400 回答
0
SELECT u.*
     , x.*
  FROM payments x
  JOIN (SELECT user_id,MAX(date) max_date FROM payments GROUP BY user_id) y
    ON y.user_id = x.user_id
   AND x.date = y.max_date
  JOIN users u
    ON u.id = x.user_id;
于 2013-06-04T15:19:14.813 回答