![](/img/trans.png)
[英]Group records by UserID, select where on one column value and sum another
[英]SELECT MAX from one column with SUM and GROUP BY for another, without subqueries
请考虑下表。
+----+------+--------+-------------+---------------------+
| id | user | amount | description | paid_on |
+----+------+--------+-------------+---------------------+
| 1 | 1 | 200 | wire | 2017-09-01 15:45:52 |
| 2 | 2 | 200 | paypal | 2017-09-09 05:05:05 |
| 3 | 3 | 150 | cash | 2017-09-02 12:34:56 |
| 4 | 1 | 20 | wire | 2017-01-09 01:23:45 |
+----+------+--------+-------------+---------------------+
我正在尝试获取每个用户的总付款以及该用户的最后付款日期。 为此,我正在使用
SELECT
user,
ROUND(SUM(amount),2) AS amount,
date_format(paid_on, '%d.%m.%Y.') AS paid_on
FROM
(
SELECT
user,
amount,
paid_on
FROM payments
WHERE paid_on BETWEEN '2017-09-01 00:00:00' AND '2017-09-30 23:59:59'
ORDER BY paid_on DESC
) tmppayments
GROUP BY user
它按照我的预期工作,因为它返回了我的想法。 但是,使用子查询似乎有点矫枉过正。 是否可以使用简单的(r)查询执行此操作,而无需借助任何子查询?
这会吗?
SELECT
user,
ROUND(SUM(amount),2) AS amount,
date_format(MAX(paid_on),'%d.%m.%Y.') AS paid_on
FROM
payments
GROUP BY user
请注意,我遗漏了BETWEEN '2017-09-01 00:00:00' AND '2017-09-30 23:59:59'
条件,因为你从来没有提到它是你想要的东西。
使用MAX
函数选择最新的paid_on
日期。
询问
select `user`,
round(sum(`amount`),2) as `amount`,
date_format(max(`paid_on`), '%d.%m.%Y.') as `paid_on`
from `payments`
where `paid_on` between '2017-09-01 00:00:00' and '2017-09-30 23:59:59'
group by `user`;
然后就是不要使用子查询:
SELECT
user,
ROUND(SUM(amount),2) AS amount,
MAX(date_format(paid_on, '%d.%m.%Y.')) AS max_paid_on
FROM payments
WHERE paid_on BETWEEN '2017-09-01 00:00:00' AND '2017-09-30 23:59:59'
GROUP BY user
虽然您应该知道子查询不一定会减慢您的查询速度,在这种情况下它可能不会
你试过这种方式吗?:
SELECT user,
ROUND(SUM(amount),2) AS amount,
date_format(max(paid_on), '%d.%m.%Y.') AS paid_on
FROM payments
WHERE paid_on BETWEEN '2017-09-01 00:00:00' AND '2017-09-30 23:59:59'
GROUP BY user
您根本不需要子查询。 而且,您还可以简化日期逻辑:
SELECT p.user, SUM(p.amount) as total_amount, MAX(p.paid_on) as max_paid_on
FROM payments p
WHERE p.paid_on >= '2017-09-01' AND p.paid_on <'2017-10-01'
GROUP BY user
ORDER BY max_paid_on DESC;
笔记:
max_paid_on
。 我更喜欢ISO标准格式,YYYY-MM-DD,以及其他任何格式。 BETWEEN
与日期或日期时间列一起使用。 这是一篇很好的博客文章,解释了为什么(尽管它适用于SQL Server,它确实适用于所有数据库)。 select
, paid_on
未被聚合,并且不在group by
。 这几乎是任何其他数据库中的错误。 SELECT
p.user,
ROUND(SUM(p.amount), 2) AS amount,
date_format(MAX(p.paid_on), '%d.%m.%Y.') AS paid_on
FROM
payments p
WHERE
p.paid_on BETWEEN '2017-09-01 00:00:00' AND '2017-09-30 23:59:59'
GROUP BY
p.user
ORDER BY
p.paid_on DESC
子查询在此处被不必要地添加。 没有子查询的最佳方法是SELECT user, ROUND(SUM(amount),2) AS amount, date_format(max(paid_on), '%d.%m.%Y.') AS paid_on FROM payments WHERE paid_on BETWEEN '2017-09-01 00:00:00' AND '2017-09-30 23:59:59' GROUP BY user
希望它SELECT user, ROUND(SUM(amount),2) AS amount, date_format(max(paid_on), '%d.%m.%Y.') AS paid_on FROM payments WHERE paid_on BETWEEN '2017-09-01 00:00:00' AND '2017-09-30 23:59:59' GROUP BY user
帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.