国产精品亚洲成在人线_中文字幕在线最新在线不卡_日本欧美一区二区三区乱码_亚洲福利一区二区

9000px;">
  • <menu id="esycg"><strong id="esycg"></strong></menu>
  • <input id="esycg"></input>

    當前位置 主頁 > 技術大全 >

      MySQL 行轉列完全指南:從基礎 CASE WHEN 到動態 SQL 的深度實踐

      欄目:技術大全 時間:2025-09-23 23:44

      MySQL中的"行轉列"是一個經典且非常實用的數據處理技巧,通常用于將數據從一種易于存儲的格式轉換為一種更易于閱讀和報告的格式。下面我將詳細解釋其概念、方法和應用場景。
      核心概念:什么是行轉列?
      - **行數據**:通常指數據庫中最自然的存儲格式,每一行代表一條獨立的記錄。
      | 學生姓名 | 科目 | 成績 |
      | :------- | :--- | :--- |
      | 張三 | 語文 | 90 |
      | 張三 | 數學 | 85 |
      | 李四 | 語文 | 95 |
      | 李四 | 數學 | 70 |
       
      - **列數據**(行轉列后的目標):將某一列的唯一值(如`科目`)轉換為新的列名,并將其對應的值(如`成績`)填充到新列下。
      | 學生姓名 | 語文 | 數學 |
      | :------- | :--- | :--- |
      | 張三 | 90 | 85 |
      | 李四 | 95 | 70 |
       
      這種轉換也稱為**數據透視(PIVOT)**。
       
      ---
       
      ### 實現行轉列的幾種方法
       
      假設我們有上文的成績表 `scores`。
       
      方法一:使用 `CASE WHEN` + 聚合函數(最通用、最靈活)
       
      這是最經典和兼容性最好的方法,適用于幾乎所有版本的 MySQL。
       
      **思路**:
      1. 使用 `GROUP BY` 按唯一標識(如`學生姓名`)分組,確保一行一個學生。
      2. 對每個需要轉換的列值,使用 `CASE WHEN`(或 `IF`)語句判斷并提取對應的值。
      3. 使用 `MAX` 或 `MIN`、`SUM` 等聚合函數對提取出的值進行聚合(通常用于確保每個分組下只有一個非空值)。
       
      **SQL 示例**:
      ```sql
      SELECT
      學生姓名,
      MAX(CASE WHEN 科目 = '語文' THEN 成績 ELSE NULL END) AS 語文,
      MAX(CASE WHEN 科目 = '數學' THEN 成績 ELSE NULL END) AS 數學
      -- , ...可以繼續添加其他科目
      FROM scores
      GROUP BY 學生姓名;
      ```
       
      **結果**:
      | 學生姓名 | 語文 | 數學 |
      | :------- | :--- | :--- |
      | 張三 | 90 | 85 |
      | 李四 | 95 | 70 |
       
      **為什么用 `MAX`?**
      因為 `GROUP BY` 后,每個學生的每門科目理論上只有一條記錄。`MAX` 的作用是取回那條唯一記錄的值。如果不用聚合函數,SQL 會報錯。你也可以用 `MIN` 或 `SUM`,效果相同。
       
      方法二:使用 `IF()` + 聚合函數(MySQL 的簡潔寫法)
       
      `IF(condition, value_if_true, value_if_false)` 是 `CASE WHEN` 的簡化版,邏輯更清晰。
       
      **SQL 示例**:
      ```sql
      SELECT
      學生姓名,
      MAX(IF(科目 = '語文', 成績, NULL)) AS 語文,
      MAX(IF(科目 = '數學', 成績, NULL)) AS 數學
      FROM scores
      GROUP BY 學生姓名;
      ```
      效果與方法一完全相同。
       
      方法三:使用 `GROUP_CONCAT`(另一種形式的“行轉列”)
       
      有時“轉列”的目的不是生成多個新列,而是將多行數據**合并到一個單元格**中,用分隔符連接。這時 `GROUP_CONCAT` 非常有用。
       
      **SQL 示例**:
      ```sql
      SELECT
      學生姓名,
      GROUP_CONCAT(科目, ':', 成績 SEPARATOR '; ') AS 成績單
      FROM scores
      GROUP BY 學生姓名;
      ```
       
      **結果**:
      | 學生姓名 | 成績單 |
      | :------- | :----------------- |
      | 張三 | 語文:90; 數學:85 |
      | 李四 | 語文:95; 數學:70 |
       
      ---
       
      高級應用:動態行轉列
       
      上面的方法有個巨大缺陷:**需要手動編寫每個要轉換的列值(如‘語文’、‘數學’)**。如果科目是不確定的(例如隨時會增加‘英語’、‘物理’),上面的 SQL 就無法滿足需求。
       
      這時需要使用**存儲過程(Stored Procedure)** 來**動態**生成 SQL 語句。
       
      **思路**:
      1. 查詢出所有需要轉換為列名的唯一值(如所有科目)。
      2. 使用字符串拼接函數(如 `CONCAT`, `GROUP_CONCAT`)構造出包含所有 `CASE WHEN` 語句的 SQL 字符串。
      3. 使用預處理語句(`PREPARE` & `EXECUTE`)來執行這個動態生成的 SQL 字符串。
       
      **示例代碼**:
      ```sql
      -- 1. 定義變量存儲動態生成的SQL
      SET @sql = NULL;
       
      -- 2. 查詢所有不重復的科目,并拼接成 MAX(CASE WHEN...) 的格式
      SELECT
      GROUP_CONCAT(DISTINCT
      CONCAT(
      'MAX(IF(科目 = ''',
      科目,
      ''', 成績, NULL)) AS ',
      CONCAT('`', 科目, '`') -- 用反引號包裹科目名,防止它是關鍵字
      )
      ) INTO @sql
      FROM scores;
       
      -- 3. 拼接完整的SQL語句
      SET @sql = CONCAT('SELECT 學生姓名, ', @sql, ' FROM scores GROUP BY 學生姓名');
       
      -- 4. 預處理并執行動態SQL
      PREPARE stmt FROM @sql;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;
      ```
       
      **執行結果**:無論科目如何變化,這段代碼都會自動生成一個將所有科目作為列名的透視表。
       
      | 學生姓名 | 語文 | 數學 | 英語 | (其他任何科目...) |
      | :------- | :--- | :--- | :--- | :------------------ |
      | 張三 | 90 | 85 | 92 | ... |
      | 李四 | 95 | 70 | 88 | ... |
       
      ---
       
      ### 總結與選擇
       
      | 方法 | 適用場景 | 優點 | 缺點 |
      | :----------------- | :--------------------------------------------- | :--------------------------- | :----------------------------- |
      | **`CASE WHEN`/`IF`** | 要轉換的列值是**固定的、已知的**(如科目固定) | 簡單、直觀、性能好 | 無法自動適應列值的變化 |
      | **`GROUP_CONCAT`** | 需要將多行數據合并到一個字段中顯示 | 非常靈活,不會改變表結構 | 結果不是一個規整的二維表 |
      | **動態SQL** | 要轉換的列值是**動態的、不確定的**(如科目可變) | 全自動,一勞永逸 | 編寫復雜,需要用到存儲過程和預處理 |
       
      **核心要點**:
      1. **行轉列的本質是條件判斷和分組聚合**。
      2. 靜態轉換使用 `CASE WHEN`/`IF` + `MAX` + `GROUP BY`。
      3. 動態轉換需要使用存儲過程拼接 SQL,復雜度較高。
      4. 在選擇方法前,一定要明確需求中的“列”是否是固定的。
      另外搭配便捷的MYSQL備份工具,可定時備份、異地備份,MYSQL導出導入?杀镜剡B接LINUX里的MYSQL,簡單便捷。可以大大地提高工作效率喔。

    MySQL 全連接(FULL OUTER JOIN)完全指南:語法、誤區與 UNION 實現方案
    MySQL刪除數據詳解:DELETE與TRUNCATE的原理、區別與正確選用
    MySQL UPDATE語句詳解:從基礎語法到多表連接更新實戰
    從備份到驗證:MySQL表字段刪除操作的標準化流程與最佳實踐
    MySQL分頁查詢詳解:從LIMIT/OFFSET基礎到鍵集分頁性能優化實戰
    告別SQL注入:詳解Python中MySQL參數化查詢的正確使用方法
    MySQL 表結構升級:ALTER TABLE ADD COLUMN 語法詳解與最佳實踐
    深度解析 MySQL 數值與字符串類型:如何精準選擇以優化存儲與性能?
    避開時區陷阱!詳解 MySQL 獲取當前時間的正確姿勢與最佳實踐
    告別NULL值陷阱!深入剖析MySQL CONCAT與CONCAT_WS的差異與最佳實踐
    国产精品亚洲成在人线_中文字幕在线最新在线不卡_日本欧美一区二区三区乱码_亚洲福利一区二区
  • <menu id="esycg"><strong id="esycg"></strong></menu>
  • <input id="esycg"></input>
  • 国产成人av电影在线播放| 国产美女在线观看一区| 99视频热这里只有精品免费| 精品少妇一区二区三区在线视频| 欧美一级艳片视频免费观看| 中国色在线观看另类| 亚洲男女毛片无遮挡| 国产99久久精品| 国模无码大尺度一区二区三区| 国产欧美精品国产国产专区| 欧美一区二区三区免费| 在线观看免费一区| 日韩av电影一区| 亚洲精品久久7777| 国产亚洲成aⅴ人片在线观看| 色国产综合视频| 国产精品白丝jk白祙喷水网站| 91精品国产综合久久久久久久| 亚洲视频一二三区| 中文字幕亚洲不卡| 亚洲视频图片小说| 亚洲丝袜美腿综合| 91精品国产色综合久久久蜜香臀| 精品一区二区影视| 亚洲人成在线播放网站岛国| 国产精品影视在线观看| 欧美情侣在线播放| a级高清视频欧美日韩| 国产69精品久久99不卡| 777色狠狠一区二区三区| 国产成人av一区| 91麻豆精品国产91久久久更新时间| 欧美一区二区三区免费视频| 欧美性色黄大片手机版| 首页国产欧美日韩丝袜| 日韩毛片精品高清免费| 欧美日韩高清一区二区| 亚洲午夜在线视频| 日韩欧美一区二区免费| 日韩视频一区二区三区在线播放| 精品国精品自拍自在线| 国产欧美视频一区二区| 久久超碰97中文字幕| 亚洲资源在线观看| 亚洲自拍欧美精品| 99久久婷婷国产精品综合| 亚洲摸摸操操av| 高清成人在线观看| 欧美日免费三级在线| 在线视频综合导航| 国产成a人亚洲精| 99re免费视频精品全部| 一区二区三区精品视频在线| 色综合久久天天综合网| 欧美视频一区在线| 制服丝袜亚洲色图| 男女性色大片免费观看一区二区| www.成人网.com| 日韩欧美国产不卡| 国产成人h网站| 免费的国产精品| 成人永久aaa| 91在线国产福利| 国产亚洲欧美一级| 97久久人人超碰| 色综合婷婷久久| 99这里只有久久精品视频| 亚洲日本在线天堂| 午夜电影一区二区三区| 欧美婷婷六月丁香综合色| 亚洲国产一区二区三区青草影视| 国产在线不卡一区| 韩国一区二区三区| 成人免费视频一区二区| 91色porny蝌蚪| 亚洲成人黄色影院| 一区二区三区免费看视频| 日韩午夜激情电影| 国产精品毛片大码女人| 97精品超碰一区二区三区| 蜜桃免费网站一区二区三区| 亚洲国产精品ⅴa在线观看| 色婷婷综合久久久| 国产精品视频一二三区| 国产麻豆精品95视频| 亚洲va中文字幕| 一本色道久久综合精品竹菊| 欧美一区二区播放| 欧美激情一区二区在线| 中文字幕综合网| 亚洲卡通动漫在线| 一区二区三区四区五区视频在线观看| 亚洲国产精品一区二区尤物区| 国内成人精品2018免费看| 欧美日韩不卡一区| 99久久精品99国产精品| 日本久久电影网| a在线播放不卡| 国产视频一区二区在线观看| 综合久久久久综合| 午夜视频一区在线观看| 国产精品美女久久久久av爽李琼| 亚洲激情六月丁香| 久久精品免视看| 久久国产精品一区二区| 亚洲国产精品激情在线观看| 日韩激情一区二区| 日本欧美久久久久免费播放网| 欧美一区二区免费| 天天影视网天天综合色在线播放| 国产精品精品国产色婷婷| 日韩天堂在线观看| 欧美精品 日韩| 国产欧美日韩中文久久| 精品成人一区二区三区四区| 欧美日韩国产小视频在线观看| 丁香亚洲综合激情啪啪综合| aaa欧美大片| 一区二区三区高清不卡| 国产精品1区2区3区在线观看| 日本色综合中文字幕| 日韩综合小视频| 亚洲国产视频直播| 国产美女精品人人做人人爽| 青青草97国产精品免费观看无弹窗版| 99久久er热在这里只有精品66| 东方aⅴ免费观看久久av| 欧美在线免费观看亚洲| 久久久综合精品| 国产亚洲精品bt天堂精选| 国产91精品精华液一区二区三区| 成人97人人超碰人人99| 国产精品主播直播| 国产精品传媒入口麻豆| 午夜免费欧美电影| 国产日韩欧美精品电影三级在线| 午夜亚洲国产au精品一区二区| 夜夜精品浪潮av一区二区三区| 国产精品第一页第二页第三页| 欧美最猛性xxxxx直播| 国产精品原创巨作av| 久久久久久久综合色一本| 91福利社在线观看| 亚洲国产欧美一区二区三区丁香婷| 久久66热偷产精品| 久久久久久久免费视频了| 亚洲成a人片综合在线| 国产91在线看| 日韩一区二区三区视频| 国产成a人无v码亚洲福利| 欧美亚日韩国产aⅴ精品中极品| 亚洲一区二区三区四区在线观看| 欧美影片第一页| 国产欧美精品一区二区三区四区| 欧美一区二区在线观看| 久久爱www久久做| 久久久久久久综合色一本| 日韩欧美一级二级三级久久久| 91麻豆精东视频| 国产精品国产三级国产普通话三级| 精品国产自在久精品国产| 怡红院av一区二区三区| 91色乱码一区二区三区| 亚洲欧美日韩国产综合在线| 色老综合老女人久久久| 欧美一区二区在线不卡| 粉嫩aⅴ一区二区三区四区| 91久久精品一区二区三| 色噜噜狠狠色综合中国| 国产午夜精品在线观看| 日本亚洲欧美天堂免费| 亚洲网友自拍偷拍| 亚洲美女免费视频| 蜜桃久久久久久| 日本高清不卡在线观看| 一区二区三区欧美激情| 午夜私人影院久久久久| 国产91精品在线观看| 国产激情偷乱视频一区二区三区| 亚洲欧洲韩国日本视频| 久久成人免费网| 高清国产一区二区三区| 视频一区免费在线观看| 国产欧美一区二区精品久导航| 99久久精品久久久久久清纯| 午夜亚洲福利老司机| 成人精品视频一区| www.在线成人| 天天亚洲美女在线视频| 黄色日韩网站视频| 暴力调教一区二区三区| 亚洲视频一二三| 国产电影一区二区三区| 国产精品18久久久久久久久久久久| 国产黄色成人av| 国产凹凸在线观看一区二区| 国产精品久久久久婷婷二区次| 国产一区二区三区av电影| 成人精品亚洲人成在线| 亚洲欧美另类小说视频|