Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SELECT MAX from one column with SUM and GROUP BY for another, without subqueries

Tags:

sql

mysql

Consider the following table.

+----+------+--------+-------------+---------------------+
| 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 |
+----+------+--------+-------------+---------------------+

I'm trying to get the total payments for each user, and the last payment date for that same user. For this, I'm using

    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

It works as I expect it to, as it returns what I had in mind. However, using a subquery seems like an overkill. Is it possible to do this with a simple(r) query, without resorting to any subqueries?

like image 715
FiddlingAway Avatar asked Dec 22 '25 14:12

FiddlingAway


1 Answers

You don't need the subquery at all. And, you can also simplify the date logic:

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;

Notes:

  • You can format max_paid_on if you like. I much prefer the ISO standard format, YYYY-MM-DD, to any other.
  • I don't recommend using BETWEEN with dates or date time columns. Here is a good blog post explaining why (although it is for SQL Server, it really applies to all databases).
  • Your query has a logical error in it. In the outer select, paid_on is not being aggregated and it is not in the group by. This would be an error in almost any other database.
  • You are right about the subquery. MySQL materializes subqueries, which is unnecessary overhead for queries that do not require the subqueries.
like image 150
Gordon Linoff Avatar answered Dec 24 '25 04:12

Gordon Linoff



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!