MySQL取分組後最新的一條數據

一、背景介紹

MySQL是當前使用最廣泛的關係型數據庫管理系統,功能強大,應用廣泛。在業務開發過程中,經常需要對數據進行分組,然後從分組中取出最新的一條數據。

例如,某電商平台需要統計每個商品的銷售情況,需要按照商品分組,然後取出每個商品最新的銷售記錄。這個需求在開發過程中非常常見。

二、基本方法

對於這個需求,我們可以使用MySQL中的子查詢和GROUP BY語句來實現。

舉例來說,假設我們有一個sales表,其中存儲了每個商品的銷售記錄:

CREATE TABLE sales (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    product_id INT NOT NULL,
    order_time DATETIME NOT NULL,
    order_quantity INT NOT NULL
);

INSERT INTO sales (product_id, order_time, order_quantity) VALUES (1, '2022-01-01', 10);
INSERT INTO sales (product_id, order_time, order_quantity) VALUES (1, '2022-01-02', 11);
INSERT INTO sales (product_id, order_time, order_quantity) VALUES (2, '2022-01-01', 5);
INSERT INTO sales (product_id, order_time, order_quantity) VALUES (2, '2022-01-03', 12);
INSERT INTO sales (product_id, order_time, order_quantity) VALUES (3, '2022-01-02', 8);
INSERT INTO sales (product_id, order_time, order_quantity) VALUES (3, '2022-01-03', 6);

我們可以使用以下SQL語句,按照product_id分組,然後取出每組中order_time最大的那條記錄:

SELECT s1.*
FROM sales s1
JOIN (
    SELECT product_id, MAX(order_time) max_time
    FROM sales
    GROUP BY product_id
) s2 ON s1.product_id = s2.product_id AND s1.order_time = s2.max_time;

該SQL語句分為兩部分,第一部分是一個子查詢,用來計算每個product_id的最大訂單時間。第二部分是一個JOIN語句,用來將sales表與第一部分查詢結果連接,以獲取最新的銷售記錄。

三、相關技巧

1. 使用LIMIT語句優化性能

雖然上述SQL語句可以正確地獲取每個product_id的最新銷售記錄,但是在sales表比較大時會性能比較差。因為該查詢會先計算出每個product_id的最大訂單時間,然後再和全部的sales表進行JOIN。

為了優化性能,我們可以使用LIMIT語句來限制JOIN所使用的行數。具體來說,我們可以將子查詢查詢結果中的每個product_id的最大訂單時間,排序後取前N個結果,然後只對這些結果執行JOIN。這樣可以大大減少JOIN所需要的行數,從而提高性能。

SELECT s1.*
FROM sales s1
JOIN (
    SELECT product_id, MAX(order_time) max_time
    FROM sales
    GROUP BY product_id
    ORDER BY max_time DESC
    LIMIT 10 -- 只取前10個結果
) s2 ON s1.product_id = s2.product_id AND s1.order_time = s2.max_time;

該SQL語句在子查詢中限制了結果集的大小,只返回了每個product_id的最近10個銷售記錄。在實際使用時,可以根據具體情況調整LIMIT的值。

2. 使用窗口函數

在MySQL 8.0版本中,新增了窗口函數相關的語法,可以簡化上述查詢。具體來說,我們可以使用ROW_NUMBER()函數生成每個product_id內的銷售記錄的排名,然後只取銷售記錄排名為1的記錄。

SELECT *
FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY order_time DESC) AS rank
    FROM sales
) s
WHERE s.rank = 1;

該SQL語句使用了窗口函數ROW_NUMBER(),並將分組方式和排序方式指定在OVER後面的子句中。該查詢會生成一個rank列,表示每個product_id內的銷售記錄的排名。最後一步只需要篩選rank為1的記錄,即每個product_id的最新銷售記錄。

四、總結

在業務開發中,經常需要對數據進行分組,然後取出每組中最新的一條數據。MySQL中提供了多種實現方式,其中常用的是子查詢和GROUP BY語句。在使用時,可以根據具體場景考慮使用LIMIT語句或者窗口函數等優化方式,以提高查詢效率。

原創文章,作者:ZRDX,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/145082.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
ZRDX的頭像ZRDX
上一篇 2024-10-26 11:55
下一篇 2024-10-26 11:55

相關推薦

  • 如何修改mysql的端口號

    本文將介紹如何修改mysql的端口號,方便開發者根據實際需求配置對應端口號。 一、為什麼需要修改mysql端口號 默認情況下,mysql使用的端口號是3306。在某些情況下,我們需…

    編程 2025-04-29
  • Python讀取CSV數據畫散點圖

    本文將從以下方面詳細闡述Python讀取CSV文件並畫出散點圖的方法: 一、CSV文件介紹 CSV(Comma-Separated Values)即逗號分隔值,是一種存儲表格數據的…

    編程 2025-04-29
  • Python中讀入csv文件數據的方法用法介紹

    csv是一種常見的數據格式,通常用於存儲小型數據集。Python作為一種廣泛流行的編程語言,內置了許多操作csv文件的庫。本文將從多個方面詳細介紹Python讀入csv文件的方法。…

    編程 2025-04-29
  • 如何用Python統計列表中各數據的方差和標準差

    本文將從多個方面闡述如何使用Python統計列表中各數據的方差和標準差, 並給出詳細的代碼示例。 一、什麼是方差和標準差 方差是衡量數據變異程度的統計指標,它是每個數據值和該數據值…

    編程 2025-04-29
  • Python多線程讀取數據

    本文將詳細介紹多線程讀取數據在Python中的實現方法以及相關知識點。 一、線程和多線程 線程是操作系統調度的最小單位。單線程程序只有一個線程,按照程序從上到下的順序逐行執行。而多…

    編程 2025-04-29
  • Python兩張表數據匹配

    本篇文章將詳細闡述如何使用Python將兩張表格中的數據匹配。以下是具體的解決方法。 一、數據匹配的概念 在生活和工作中,我們常常需要對多組數據進行比對和匹配。在數據量較小的情況下…

    編程 2025-04-29
  • Python爬取公交數據

    本文將從以下幾個方面詳細闡述python爬取公交數據的方法: 一、準備工作 1、安裝相關庫 import requests from bs4 import BeautifulSou…

    編程 2025-04-29
  • Python數據標準差標準化

    本文將為大家詳細講述Python中的數據標準差標準化,以及涉及到的相關知識。 一、什麼是數據標準差標準化 數據標準差標準化是數據處理中的一種方法,通過對數據進行標準差標準化可以將不…

    編程 2025-04-29
  • 如何使用Python讀取CSV數據

    在數據分析、數據挖掘和機器學習等領域,CSV文件是一種非常常見的文件格式。Python作為一種廣泛使用的編程語言,也提供了方便易用的CSV讀取庫。本文將介紹如何使用Python讀取…

    編程 2025-04-29
  • Python如何打亂數據集

    本文將從多個方面詳細闡述Python打亂數據集的方法。 一、shuffle函數原理 shuffle函數是Python中的一個內置函數,主要作用是將一個可迭代對象的元素隨機排序。 在…

    編程 2025-04-29

發表回復

登錄後才能評論