簡體   English   中英

使用SUM和GROUP BY從一列中選擇MAX,而不使用子查詢

[英]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,它確實適用於所有數據庫)。
  • 您的查詢中存在邏輯錯誤。 在外部selectpaid_on未被聚合,並且不在group by 這幾乎是任何其他數據庫中的錯誤。
  • 你對子查詢是正確的。 MySQL實現了子查詢,這對於不需要子查詢的查詢來說是不必要的開銷。
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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM