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

一文帶你解鎖MySQL實現(xiàn)行轉(zhuǎn)列的完整方法

 更新時間:2026年01月28日 08:29:29   作者:detayun  
MySQL的行轉(zhuǎn)列,不是簡單的語法堆砌,而是對數(shù)據(jù)結(jié)構(gòu)深刻理解后的重構(gòu),這篇文章主要介紹了MySQL實現(xiàn)行轉(zhuǎn)列的完整方法,有需要的小伙伴可以了解下

在數(shù)據(jù)處理的江湖中,我們常面臨這樣一種尷尬的局面:數(shù)據(jù)庫里的數(shù)據(jù)明明就在那里,卻像是一堆散亂的拼圖,無法以直觀的報表形式呈現(xiàn)。比如,學(xué)生的成績單,數(shù)據(jù)庫里存的是“張三-語文-90”、“張三-數(shù)學(xué)-92”這樣的行記錄,而我們要看的卻是“張三 | 語文90 | 數(shù)學(xué)92”這樣的寬表。

這就是行轉(zhuǎn)列(Pivot)的戰(zhàn)場。MySQL雖然不像Oracle或SQL Server那樣原生支持PIVOT關(guān)鍵字,但它提供了足夠鋒利的利器。今天,我們就來剝開行轉(zhuǎn)列的核心原理,掌握這門數(shù)據(jù)煉金術(shù)。

一、 核心心法:聚合+條件判斷

行轉(zhuǎn)列的本質(zhì),是將“行的維度”壓縮,轉(zhuǎn)化為“列的維度”。實現(xiàn)這一魔術(shù)的核心公式只有一條:

GROUP BY + 聚合函數(shù)(SUM/MAX/MIN) + 條件判斷(CASE WHEN/IF)

如果沒有聚合函數(shù),多行數(shù)據(jù)無法坍縮為一行;如果沒有條件判斷,數(shù)據(jù)無法精準地填充到對應(yīng)的列中。

經(jīng)典招式:CASE WHEN與SUM(IF)的對決

假設(shè)我們有一張成績表 tb_score,存儲了用戶ID、科目和分數(shù)。我們要將其轉(zhuǎn)為以用戶ID為行,各科目為列的報表。

場景數(shù)據(jù)

CREATE TABLE tb_score(
    id INT AUTO_INCREMENT,
    userid VARCHAR(20),
    subject VARCHAR(20),
    score DOUBLE,
    PRIMARY KEY(id)
);
INSERT INTO tb_score(userid,subject,score) VALUES 
('001','語文',90), ('001','數(shù)學(xué)',92), ('001','英語',80),
('002','語文',88), ('002','數(shù)學(xué)',90), ('002','英語',75.5);

招式一:CASE WHEN(標準SQL,通用性強)

SELECT 
    userid,
    SUM(CASE subject WHEN '語文' THEN score ELSE 0 END) AS '語文',
    SUM(CASE subject WHEN '數(shù)學(xué)' THEN score ELSE 0 END) AS '數(shù)學(xué)',
    SUM(CASE subject WHEN '英語' THEN score ELSE 0 END) AS '英語'
FROM tb_score 
GROUP BY userid;

招式二:SUM(IF(...))(MySQL特色,簡潔高效)

SELECT 
    userid,
    SUM(IF(subject='語文', score, 0)) AS '語文',
    SUM(IF(subject='數(shù)學(xué)', score, 0)) AS '數(shù)學(xué)',
    SUM(IF(subject='英語', score, 0)) AS '英語'
FROM tb_score 
GROUP BY userid;

高手進階:為什么用SUM?

很多人會問:明明每個用戶每個科目只有一條記錄,為什么不用MAXMIN?

這里有一個關(guān)鍵細節(jié):SUM在這里不僅是求和,更是為了配合GROUP BY進行行坍縮。

  • 如果你確定每個分組只有一個非NULL值,SUMMAX、MIN、AVG 效果一樣。
  • 但如果數(shù)據(jù)存在重復(fù)(比如誤錄了兩條語文成績),SUM會將其相加,而MAX只取最大值。根據(jù)業(yè)務(wù)需求選擇聚合函數(shù),是行轉(zhuǎn)列的精髓所在。通常建議使用MAXSUM,并將ELSE設(shè)為0而非NULL,以免污染計算結(jié)果。

二、 奇門遁甲:應(yīng)對復(fù)雜場景

基礎(chǔ)的行轉(zhuǎn)列只能解決靜態(tài)列的問題,面對動態(tài)列、列轉(zhuǎn)行或字符串聚合,我們需要更高級的戰(zhàn)術(shù)。

1. 字符串聚合:GROUP_CONCAT

如果不想要數(shù)值列,而是想把多行文本合并成一個字符串(比如合并標簽),GROUP_CONCAT是神器。

-- 將同一用戶的所有分數(shù)合并顯示
SELECT userid, GROUP_CONCAT(score) AS all_scores 
FROM tb_score 
GROUP BY userid;

2. 列轉(zhuǎn)行(Unpivot):UNION ALL

這是行轉(zhuǎn)列的逆操作。如果表結(jié)構(gòu)是 userid | 語文 | 數(shù)學(xué) | 英語,想轉(zhuǎn)回行結(jié)構(gòu):

SELECT userid, '語文' AS subject, 語文 AS score FROM tb_score_wide
UNION ALL
SELECT userid, '數(shù)學(xué)' AS subject, 數(shù)學(xué) AS score FROM tb_score_wide
UNION ALL
SELECT userid, '英語' AS subject, 英語 AS score FROM tb_score_wide;

雖然寫法繁瑣,但這是SQL標準處理列轉(zhuǎn)行的不二法門。

3. 動態(tài)行轉(zhuǎn)列:預(yù)處理語句(Prepared Statement)

這是最考驗功力的一招。當科目(列名)不確定,可能隨時增加“物理”、“化學(xué)”時,寫死SQL是不可能的。必須動態(tài)生成SQL語句并執(zhí)行。

核心邏輯

  • 查詢出所有不重復(fù)的列名(如科目)。
  • 拼接成 SUM(CASE...) 的字符串。
  • PREPAREEXECUTE 執(zhí)行動態(tài)SQL。
SET @sql = NULL;
SELECT GROUP_CONCAT(
    DISTINCT CONCAT('SUM(CASE subject WHEN ''', subject, ''' THEN score ELSE 0 END) AS `', subject, '`')
) INTO @sql 
FROM tb_score;

SET @sql = CONCAT('SELECT userid, ', @sql, ' FROM tb_score GROUP BY userid');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

這段代碼能自動適應(yīng)表中所有的科目,是生成動態(tài)報表的終極武器。

三、 實戰(zhàn)錦囊:性能與優(yōu)化

行轉(zhuǎn)列雖然強大,但也是性能殺手。因為它需要全表掃描并進行分組排序,數(shù)據(jù)量大時極易拖慢數(shù)據(jù)庫。

  • 索引是救命稻草:務(wù)必在 GROUP BY 的字段(如userid)和條件判斷的字段(如subject)上建立復(fù)合索引。沒有索引的行轉(zhuǎn)列就是災(zāi)難。
  • 緩存是王道:對于變化不頻繁的統(tǒng)計報表(如月度銷售匯總),不要每次查詢都實時計算。將行轉(zhuǎn)列的結(jié)果存入Redis或另一張匯總表,是明智的工程選擇。
  • 避免過度使用:不要在應(yīng)用層頻繁請求動態(tài)行轉(zhuǎn)列。如果列是固定的,就寫死SQL;只有在列完全不可預(yù)知時,才動用動態(tài)SQL。

結(jié)語

MySQL的行轉(zhuǎn)列,不是簡單的語法堆砌,而是對數(shù)據(jù)結(jié)構(gòu)深刻理解后的重構(gòu)。從死板的CASE WHEN到靈活的動態(tài)SQL,每一種方法都對應(yīng)著特定的業(yè)務(wù)痛點。

掌握它,你就掌握了將“丑數(shù)據(jù)”變?yōu)?ldquo;黃金報表”的能力。在數(shù)據(jù)分析的道路上,這不僅是一門技術(shù),更是一門藝術(shù)?,F(xiàn)在,打開你的MySQL客戶端,開始你的煉金之旅吧!

到此這篇關(guān)于一文帶你解鎖MySQL實現(xiàn)行轉(zhuǎn)列的完整方法的文章就介紹到這了,更多相關(guān)MySQL行轉(zhuǎn)列內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mysql中SUBSTRING函數(shù)的具體使用

    Mysql中SUBSTRING函數(shù)的具體使用

    本文主要介紹了Mysql中SUBSTRING函數(shù)的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-07-07
  • MySQL性能指標TPS+QPS+IOPS壓測

    MySQL性能指標TPS+QPS+IOPS壓測

    這篇文章主要介紹了MySQL性能指標TPS+QPS+IOPS壓測,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-08-08
  • SQL語句實現(xiàn)多表查詢

    SQL語句實現(xiàn)多表查詢

    這篇文章主要介紹了SQL語句實現(xiàn)多表查詢,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參一下下面文章詳細內(nèi)容
    2022-07-07
  • MySQL5.x版本亂碼問題解決方案

    MySQL5.x版本亂碼問題解決方案

    這篇文章主要介紹了MySQL5.x版本亂碼問題解決方案,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • MySQL中in和exists區(qū)別詳解

    MySQL中in和exists區(qū)別詳解

    最近在寫SQL語句時,對選擇IN 還是Exists猶豫不決,所以就上網(wǎng)查詢了一下資料,本文就詳細的介紹了兩個方法的區(qū)別,感興趣的可以了解一下
    2021-06-06
  • MySQL三大日志之redo?log、undo?log、binlog示例詳解

    MySQL三大日志之redo?log、undo?log、binlog示例詳解

    在MySQL數(shù)據(jù)庫的運行機制中,Redo Log、Undo Log和Binlog起著至關(guān)重要的作用,它們各司其職,共同保障數(shù)據(jù)庫的數(shù)據(jù)安全、事務(wù)一致性以及高效的復(fù)制與恢復(fù)功能,這篇文章主要介紹了MySQL三大日志之redo?log、undo?log、binlog的相關(guān)資料,需要的朋友可以參考下
    2025-09-09
  • MySQL使用B+Tree當索引的優(yōu)勢有哪些

    MySQL使用B+Tree當索引的優(yōu)勢有哪些

    這篇文章主要介紹了MySQL使用B+Tree當索引有哪些優(yōu)勢,幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下
    2021-03-03
  • MySQL添加索引及添加字段并建立索引方式

    MySQL添加索引及添加字段并建立索引方式

    這篇文章主要介紹了MySQL添加索引及添加字段并建立索引方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • MySQL數(shù)據(jù)庫高可用HA實現(xiàn)小結(jié)

    MySQL數(shù)據(jù)庫高可用HA實現(xiàn)小結(jié)

    MySQL數(shù)據(jù)庫是目前開源應(yīng)用最大的關(guān)系型數(shù)據(jù)庫,有海量的應(yīng)用將數(shù)據(jù)存儲在MySQL數(shù)據(jù)庫中,這篇文章主要介紹了MySQL數(shù)據(jù)庫高可用HA實現(xiàn),需要的朋友可以參考下
    2022-01-01
  • mysql數(shù)據(jù)庫索引損壞及修復(fù)經(jīng)驗分享

    mysql數(shù)據(jù)庫索引損壞及修復(fù)經(jīng)驗分享

    這篇文章主要介紹了mysql數(shù)據(jù)庫索引損壞及修復(fù)經(jīng)驗分享,需要的朋友可以參考下
    2015-06-06

最新評論

长海县| 大理市| 乐清市| 吴江市| 湖口县| 石家庄市| 东丽区| 平昌县| 赤城县| 武陟县| 夏河县| 仙游县| 南川市| 望谟县| 东光县| 视频| 定襄县| 曲周县| 邢台市| 平定县| 股票| 陆良县| 全州县| 瑞丽市| 大埔区| 咸阳市| 沾化县| 陈巴尔虎旗| 铜川市| 恩平市| 霍林郭勒市| 炉霍县| 治县。| 密云县| 绥阳县| 嘉定区| 叶城县| 收藏| 乐安县| 萝北县| 武穴市|