溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Mysql怎么實現多行轉一行

發布時間:2021-09-16 14:51:13 來源:億速云 閱讀:256 作者:chen 欄目:大數據
# MySQL怎么實現多行轉一行

## 引言

在數據庫操作中,我們經常會遇到需要將多行數據合并成一行的場景。例如將某個分組下的多條記錄合并為一條記錄展示,或將多行文本拼接成單個字符串。MySQL提供了多種實現方式,本文將詳細介紹5種常用方法及其適用場景。

## 一、GROUP_CONCAT函數

### 1.1 基本語法
```sql
GROUP_CONCAT([DISTINCT] column_name 
             [ORDER BY sort_column ASC/DESC] 
             [SEPARATOR '分隔符'])

1.2 典型示例

-- 基礎用法
SELECT department_id, 
       GROUP_CONCAT(employee_name) AS employees
FROM employees
GROUP BY department_id;

-- 帶分隔符和排序
SELECT product_id,
       GROUP_CONCAT(DISTINCT tag_name ORDER BY tag_id SEPARATOR '|') 
FROM product_tags
GROUP BY product_id;

1.3 注意事項

  • 默認最大返回長度1024字節(可通過group_concat_max_len參數調整)
  • NULL值會被自動忽略
  • 性能隨數據量增長可能下降

二、使用子查詢與字符串函數

2.1 適用于較老版本MySQL

SELECT 
    user_id,
    (SELECT GROUP_CONCAT(order_id) 
     FROM orders 
     WHERE user_id = u.user_id) AS order_list
FROM users u;

2.2 結合CONCAT_WS使用

SELECT 
    department,
    CONCAT_WS(',', 
        MAX(CASE WHEN seq = 1 THEN name END),
        MAX(CASE WHEN seq = 2 THEN name END)
    ) AS members
FROM (
    SELECT 
        department,
        name,
        @rn := IF(@dept = department, @rn + 1, 1) AS seq,
        @dept := department
    FROM employees, (SELECT @rn := 0, @dept := '') r
    ORDER BY department, name
) t
GROUP BY department;

三、使用存儲過程實現

3.1 創建動態拼接存儲過程

DELIMITER //
CREATE PROCEDURE concat_employee_names(IN dept_id INT)
BEGIN
    DECLARE result TEXT DEFAULT '';
    DECLARE done INT DEFAULT FALSE;
    DECLARE emp_name VARCHAR(100);
    
    DECLARE cur CURSOR FOR 
        SELECT name FROM employees WHERE department_id = dept_id;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
    OPEN cur;
    read_loop: LOOP
        FETCH cur INTO emp_name;
        IF done THEN
            LEAVE read_loop;
        END IF;
        SET result = CONCAT(result, emp_name, ',');
    END LOOP;
    CLOSE cur;
    
    SELECT dept_id AS department_id, 
           LEFT(result, LENGTH(result)-1) AS employee_list;
END //
DELIMITER ;

四、使用JSON函數(MySQL 5.7+)

4.1 JSON_ARRAYAGG

SELECT 
    department_id,
    JSON_ARRAYAGG(employee_name) AS json_employee_array
FROM employees
GROUP BY department_id;

4.2 JSON_OBJECTAGG

SELECT 
    project_id,
    JSON_OBJECTAGG(employee_id, hours_worked) AS team_hours
FROM project_assignments
GROUP BY project_id;

五、使用WITH ROLLUP擴展

5.1 配合GROUP_CONCAT使用

SELECT 
    IFNULL(department, 'ALL') AS department,
    GROUP_CONCAT(DISTINCT position) AS positions,
    COUNT(*) AS employee_count
FROM employees
GROUP BY department WITH ROLLUP;

性能對比

方法 適用版本 性能表現 功能復雜度
GROUP_CONCAT 4.1+ ★★★★☆ ★★☆☆☆
子查詢拼接 所有版本 ★★☆☆☆ ★★★☆☆
存儲過程 所有版本 ★★★☆☆ ★★★★☆
JSON函數 5.7+ ★★★★☆ ★★★☆☆
WITH ROLLUP 4.1+ ★★★☆☆ ★★★☆☆

實際應用場景

場景1:電商SKU屬性合并

SELECT 
    product_id,
    GROUP_CONCAT(
        CONCAT(attr_name, ':', attr_value) 
        SEPARATOR '; '
    ) AS product_attributes
FROM product_specs
GROUP BY product_id;

場景2:權限角色合并

SELECT 
    u.user_id,
    u.username,
    GROUP_CONCAT(r.role_name ORDER BY r.role_level DESC) AS roles
FROM users u
JOIN user_roles ur ON u.user_id = ur.user_id
JOIN roles r ON ur.role_id = r.role_id
GROUP BY u.user_id, u.username;

常見問題解決方案

問題1:結果截斷

-- 臨時設置更大的長度限制
SET SESSION group_concat_max_len = 1000000;
SELECT GROUP_CONCAT(...);

問題2:包含特殊字符

-- 使用REPLACE處理分隔符沖突
SELECT 
    GROUP_CONCAT(REPLACE(text_field, ',', ',') SEPARATOR ',')
FROM table;

總結

MySQL實現多行轉一行主要有以下幾種方式: 1. 優先推薦:GROUP_CONCAT(簡單高效) 2. 復雜邏輯:存儲過程(靈活可控) 3. 現代方案:JSON函數(結構化輸出) 4. 兼容方案:子查詢拼接(低版本兼容)

根據實際業務需求選擇合適的方法,同時注意處理大數據量時的性能問題。對于超大數據集,建議在應用層進行處理。 “`

注:本文實際約1500字,完整版可根據需要擴展具體示例和性能測試數據。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女