mysql列轉(zhuǎn)行方法超詳細講解
一、列轉(zhuǎn)行
mysql 數(shù)據(jù)庫中,我們可能遇到將數(shù)據(jù)庫中某一列的數(shù)據(jù)(多個值,按照英文逗號分隔),轉(zhuǎn)化為多行數(shù)據(jù)(即一行轉(zhuǎn)多行),然后join關(guān)聯(lián)表,再轉(zhuǎn)化為一行數(shù)據(jù)
如:有兩張表,一用戶表,一張學(xué)科表,需要查詢學(xué)科表中的用戶姓名
用戶表
| id | username | age |
| 1 | zhangsan | 20 |
| 2 | lisi | 21 |
| 3 | wamhwu | 22 |
學(xué)科表
| id | user_ids | subject |
| 1 | 1,2,3 | 數(shù)學(xué) |
| 2 | 2,3 | 語文 |
| 3 | 1,2 | 英語 |
我們首先需要把學(xué)科表中的user_ids拆分成多行
| id | user_id | subject |
| 1 | 1 | 數(shù)學(xué) |
| 1 | 2 | 數(shù)學(xué) |
| 1 | 3 | 數(shù)學(xué) |
| 2 | 2 | 語文 |
| 2 | 3 | 語文 |
| 3 | 1 | 英語 |
| 3 | 2 | 英語 |
二、普通的實現(xiàn)方式(需要依賴 mysql.help_topic 表)
SELECT
a.id,
a.subject,
SUBSTRING_INDEX( SUBSTRING_INDEX( a.`user_ids`, ',', b.help_topic_id + 1 ), ',',-1 ) user_id
FROM
test a
JOIN mysql.help_topic b ON b.help_topic_id < ( LENGTH( a.`user_ids`) - LENGTH( REPLACE ( a.`user_ids`, ',', '' ) ) + 1 );三、mysql.help_topic 無權(quán)限處理辦法
mysql.help_topic 的作用是對 SUBSTRING_INDEX 函數(shù)出來的數(shù)據(jù)(也就是按照分割符分割出來的)數(shù)據(jù)連接起來做笛卡爾積。
如果 mysql.help_topic 沒有權(quán)限,可以自己創(chuàng)建一張臨時表,用來與要查詢的表連接查詢。
獲取該字段最多可以分割成為幾個字符串:
SELECT MAX(LENGTH(a.`user_ids`) - LENGTH(REPLACE(a.`user_ids`, ',', '' )) + 1) FROM `test` a;
創(chuàng)建臨時表,并給臨時表添加數(shù)據(jù):
注意:
- 臨時表必須有一列從 0 或者 1 開始的自增數(shù)據(jù)
- 臨時表表名隨意,字段可以只有一個
- 臨時表示的數(shù)據(jù)量必須比
MAX(LENGTH(a.user_ids) - LENGTH(REPLACE(a.user_ids, ',', '' )) + 1)的值大
DROP TABLE IF EXISTS `tmp_help_topic`; CREATE TABLE IF NOT EXISTS `tmp_help_topic` ( `help_topic_id` bigint(20) NOT NULL AUTO_INCREMENT , PRIMARY KEY (`help_topic_id`) ); INSERT INTO `tmp_help_topic`() VALUES (); INSERT INTO `tmp_help_topic`() VALUES (); INSERT INTO `tmp_help_topic`() VALUES (); INSERT INTO `tmp_help_topic`() VALUES (); INSERT INTO `tmp_help_topic`() VALUES (); INSERT INTO `tmp_help_topic`() VALUES (); INSERT INTO `tmp_help_topic`() VALUES (); INSERT INTO `tmp_help_topic`() VALUES (); INSERT INTO `tmp_help_topic`() VALUES (); INSERT INTO `tmp_help_topic`() VALUES ();
四、查詢函數(shù)
SELECT
a.id,a.subject,SUBSTRING_INDEX(SUBSTRING_INDEX(a.`user_ids`, ',', b.help_topic_id), ',',-1 ) user_id
FROM
test a
JOIN tmp_help_topic b ON b.help_topic_id <= (LENGTH( a.`user_ids`) - LENGTH(REPLACE(a.`user_ids`, ',', '')) + 1 );五、join用戶表,關(guān)聯(lián)用戶名
select
t2.*,
u.username
from (
SELECT
a.id,a.subject,SUBSTRING_INDEX(SUBSTRING_INDEX(a.`user_ids`, ',', b.help_topic_id), ',',-1 ) user_id
FROM
test a
JOIN tmp_help_topic b ON b.help_topic_id <= (LENGTH( a.`user_ids`) - LENGTH(REPLACE(a.`user_ids`, ',', '')) + 1 )
) t2 join user u
on u.id = t2.user_id| id | user_id | subject | username |
| 1 | 1 | 數(shù)學(xué) | zhangsan |
| 1 | 2 | 數(shù)學(xué) | lisi |
| 1 | 3 | 數(shù)學(xué) | wangwu |
| 2 | 2 | 語文 | lisi |
| 2 | 3 | 語文 | wangwu |
| 3 | 1 | 英語 | zhangsan |
| 3 | 2 | 英語 | lisi |
六、將多行數(shù)據(jù)轉(zhuǎn)化為一行
select
t2.*,
group_concat(u.username) username
from (
SELECT
a.id,a.subject,SUBSTRING_INDEX(SUBSTRING_INDEX(a.`user_ids`, ',', b.help_topic_id), ',',-1 ) user_id
FROM
test a
JOIN tmp_help_topic b ON b.help_topic_id <= (LENGTH( a.`user_ids`) - LENGTH(REPLACE(a.`user_ids`, ',', '')) + 1 )
) t2 join user u
on u.id = t2.user_id
group by t2.id| id | subject | user_ids | username |
| 1 | 數(shù)學(xué) | 1,2,3 | zhangsan,lisi,wangwu |
| 2 | 語文 | 2,3 | lisi,wangwu |
| 3 | 英語 | 1,2 | zhangsan,lisi |
說明:
- SUBSTRING_INDEX(SUBSTRING_INDEX(a.user_ids, ',', b.help_topic_id), ',',-1 ) 就是獲取 tmp_help_topic 表的 help_topic_id 字段的值作為 name 字段的第幾個子串
- 使用了 join 就會把字段 user_ids 分為 (LENGTH( a.user_ids) - LENGTH(REPLACE(a.user_ids, ',', '')) + 1 ) 行,并且每行的字段剛好是 user_ids字段的第 help_topic_id 個子串
GROUP_CONCAT函數(shù)用于將GROUP BY產(chǎn)生的同一個分組中的值連接起來,返回一個字符串結(jié)果
GROUP_CONCAT函數(shù)首先根據(jù)GROUP BY指定的列進行分組,將同一組的列顯示出來,并且用分隔符分隔,由函數(shù)參數(shù)(字段名)決定要返回的列
語法結(jié)構(gòu)
GROUP_CONCAT([DISTINCT] 要連接的字段 [ORDER BY 排序字段 ASC/DESC] [SEPARATOR '分隔符'])
說明:
(1) 使用DISTINCT可以排除重復(fù)值
(2) 如果需要對結(jié)果中的值進行排序,可以使用ORDER BY子句
(3) SEPARATOR '分隔符'是一個字符串值,默認為逗號
總結(jié)
到此這篇關(guān)于mysql列轉(zhuǎn)行方法的文章就介紹到這了,更多相關(guān)mysql列轉(zhuǎn)行內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Windows7下Python3.4使用MySQL數(shù)據(jù)庫
這篇文章主要為大家詳細介紹了Windows7下Python3.4使用MySQL數(shù)據(jù)庫,MySQL Community Server的安裝步驟,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07
mysql如何實現(xiàn)多行查詢結(jié)果合并成一行
利用函數(shù):group_concat(),實現(xiàn)一個ID對應(yīng)多個名稱時,原本為多行數(shù)據(jù),把名稱合并成一行2013-12-12
Navicat連接mysql報錯2003(10060)的解決方法
本來好好的navicat連接數(shù)據(jù)庫,突然間今天就打不開數(shù)據(jù)庫了,下面這篇文章主要給大家介紹了關(guān)于Navicat連接mysql報錯2003(10060)的解決方法,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2023-04-04

