最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL 中 ROW_NUMBER() 函數(shù)最佳實踐

 更新時間:2025年06月26日 15:09:06   作者:比特森林探險記  
MySQL中ROW_NUMBER()函數(shù),作為窗口函數(shù)為每行分配唯一連續(xù)序號,區(qū)別于RANK()和DENSE_RANK(),特別適合分頁、去重、TopN等需要精確順序控制的場景,本文給大家介紹MySQL中ROW_NUMBER()函數(shù),感興趣的朋友一起看看吧

MySQL 中 ROW_NUMBER() 函數(shù)詳解

ROW_NUMBER() 是 SQL 窗口函數(shù)中的一種,用于為查詢結果集中的每一行分配一個??唯一的連續(xù)序號??。與 RANK() 和 DENSE_RANK() 不同,ROW_NUMBER() 不會處理重復值,即使排序字段值相同,也會嚴格按行順序遞增編號。

一、基礎語法

ROW_NUMBER() OVER (
    [PARTITION BY 分組字段]
    ORDER BY 排序字段 [ASC|DESC]
)
  • ??PARTITION BY??:按指定字段分組,每組內重新從1開始編號。
  • ??ORDER BY??:決定排序邏輯,影響行號的分配順序。

二、核心特點

??特性????說明??
唯一性每行序號嚴格遞增,不重復(即使排序字段值相同)
靈活性可結合分組(PARTITION BY)實現(xiàn)復雜場景
兼容性MySQL 8.0+ 原生支持,低版本需用變量模擬
性能影響未優(yōu)化時可能導致全表掃描,需合理使用索引

三、典型應用場景

1. 數(shù)據分頁查詢

-- 查詢第3頁數(shù)據(每頁10條)
WITH paged_data AS (
    SELECT 
        id, name, 
        ROW_NUMBER() OVER (ORDER BY id) AS row_num
    FROM users
)
SELECT * 
FROM paged_data 
WHERE row_num BETWEEN 21 AND 30;

2. 刪除重復數(shù)據

-- 保留最新記錄(假設 create_time 為時間戳)
DELETE FROM orders
WHERE (id, product_id) IN (
    SELECT id, product_id FROM (
        SELECT 
            id, product_id,
            ROW_NUMBER() OVER (
                PARTITION BY product_id 
                ORDER BY create_time DESC
            ) AS rn
        FROM orders
    ) t 
    WHERE rn > 1  -- 刪除重復項,保留最新一條
);

3. 分組取Top N記錄

-- 獲取每個部門薪資前3名
SELECT *
FROM (
    SELECT 
        name, department, salary,
        ROW_NUMBER() OVER (
            PARTITION BY department 
            ORDER BY salary DESC
        ) AS dept_rank
    FROM employees
) ranked
WHERE dept_rank <= 3;

4. 生成唯一流水號

-- 按日期生成訂單流水號(格式:YYYYMMDD-0001)
SELECT 
    order_id,
    CONCAT(
        DATE_FORMAT(create_time, '%Y%m%d'), 
        '-', 
        LPAD(ROW_NUMBER() OVER (
            PARTITION BY DATE(create_time) 
            ORDER BY create_time
        ), 4, '0')
    ) AS serial_num
FROM orders;

四、與其他排序函數(shù)對比

函數(shù)重復值處理示例結果(排序字段值相同)
ROW_NUMBER()強制分配不同序號1, 2, 3, 4
RANK()相同值共享排名,后續(xù)跳過序號1, 1, 3, 4
DENSE_RANK()相同值共享排名,后續(xù)連續(xù)遞增1, 1, 2, 3
-- 對比三種函數(shù)
SELECT 
    score,
    ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num,
    RANK() OVER (ORDER BY score DESC) AS rank,
    DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rank
FROM exam_scores;

五、性能優(yōu)化技巧

1. 索引設計

為 PARTITION BY 和 ORDER BY 涉及的字段創(chuàng)建聯(lián)合索引:

CREATE INDEX idx_dept_salary ON employees(department, salary DESC);

2. 減少計算范圍

-- 僅處理2023年數(shù)據
SELECT *
FROM (
    SELECT 
        order_id, amount,
        ROW_NUMBER() OVER (ORDER BY amount DESC) AS rn
    FROM orders
    WHERE YEAR(order_date) = 2023  -- 先過濾再排序
) t
WHERE rn <= 100;

3. 避免嵌套查詢

-- 優(yōu)化前(性能差)
SELECT * FROM (
    SELECT *, ROW_NUMBER() OVER (...) AS rn
    FROM large_table
) t WHERE rn <= 100;
-- 優(yōu)化后(直接使用LIMIT,若邏輯允許)
SELECT *, ROW_NUMBER() OVER (...) AS rn
FROM large_table
ORDER BY ...
LIMIT 100;

六、MySQL低版本兼容方案(5.7及以下)

使用會話變量模擬 ROW_NUMBER()

-- 按部門分組排序
SELECT 
    department, name, salary,
    @row_num := IF(
        @current_dept = department, 
        @row_num + 1, 
        1
    ) AS row_num,
    @current_dept := department AS dummy
FROM employees
ORDER BY department, salary DESC;

七、常見錯誤與排查

1. 錯誤:序號不符合預期

  • ??原因??:未正確指定 ORDER BY 或 PARTITION BY
  • ??解決??:檢查排序字段是否明確,分組條件是否合理

2. 錯誤:性能低下

  • ??原因??:未使用索引導致全表掃描
  • ??解決??:使用 EXPLAIN 分析執(zhí)行計劃,添加必要索引

3. 錯誤:結果集為空

  • ??原因??:外層查詢條件與子查詢中的 WHERE 沖突
  • ??解決??:驗證過濾條件邏輯

八、最佳實踐

  • ??明確排序規(guī)則??:始終顯式指定 ORDER BY 的排序方向(ASC/DESC)
  • ??慎用全局排序??:避免無 PARTITION BY 的大數(shù)據集操作
  • ??監(jiān)控內存使用??:窗口函數(shù)可能消耗大量臨時內存
  • ??版本驗證??:生產環(huán)境確認 MySQL 版本 >= 8.0
  • ??結合 CTE 使用??:提高復雜查詢的可讀性
WITH ranked_products AS (
    SELECT 
        product_id,
        ROW_NUMBER() OVER (PARTITION BY category ORDER BY sales DESC) AS rn
    FROM products
)
SELECT * FROM ranked_products WHERE rn = 1;

??總結??:ROW_NUMBER() 是處理行級序號分配的利器,特別適合需要精確控制行順序的場景。合理使用可顯著簡化分頁、去重、Top N查詢等操作,但需注意其對性能的影響,尤其在處理海量數(shù)據時需結合索引優(yōu)化。

到此這篇關于MySQL 中 ROW_NUMBER() 函數(shù)詳解的文章就介紹到這了,更多相關mysql row_number()函數(shù)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

玉溪市| 鄱阳县| 武宣县| 扎赉特旗| 克什克腾旗| 阜新市| 江达县| 芦溪县| 保德县| 咸丰县| 长岛县| 濉溪县| 安龙县| 德惠市| 武宣县| 临泽县| 红原县| 庄浪县| 侯马市| 安仁县| 抚远县| 西平县| 阿合奇县| 永善县| 吉木乃县| 汉阴县| 海宁市| 库尔勒市| 塔河县| 海兴县| 桂东县| 治县。| 铁力市| 同德县| 延边| 遂昌县| 唐山市| 孝义市| 汉阴县| 山东省| 集贤县|