2009-11-04 171 views
1

簡單問一下,mysql中是否有任何函數可用於將單個行元素拆分爲多個列? 我有一個表的行,user_id, user_name, user_location.如何在mysql中將單個行拆分成多個列

在這個用戶可以添加多個位置。我內爆的地點和存儲在一張表使用PHP單行。

當我在網格視圖中顯示用戶記錄時,我得到分頁問題,​​因爲我通過分割user_locations來顯示記錄。所以我需要拆分user_locations(單行到多列)。

mysql中是否有任何函數可以按字符(%)對記錄進行拆分和計數。

例如具有US%UK%JAPAN%CANADA

如何可以在至4列分割此記錄的USER_LOCATION。 我還需要檢查計數值(4)。提前致謝。

回答

2

首先規格化字符串,刪除空的位置,並確保最後有一個%:

select replace(concat(user_location,'%'),'%%','%') as str 
from YourTable where user_id = 1 

然後我們可以用一個技巧來計算條目的數量。將'%'替換爲'%',並計算添加到字符串的空格數。例如:

select length(replace(str, '%', '% ')) - length(str) 
    as LocationCount  
from (
    select replace(concat(user_location,'%'),'%%','%') as str 
    from YourTable where user_id = 1 
) normalized 

使用SUBSTRING_INDEX,我們可以爲多個位置添加列:

select length(replace(str, '%', '% ')) - length(str) 
    as LocationCount  
, substring_index(substring_index(str,'%',1),'%',-1) as Loc1 
, substring_index(substring_index(str,'%',2),'%',-1) as Loc2 
, substring_index(substring_index(str,'%',3),'%',-1) as Loc3 
from (
    select replace(concat(user_location,'%'),'%%','%') as str 
    from YourTable where user_id = 1 
) normalized 

對於示例US%UK%JAPAN%CANADA,這個打印:

​​

所以你看它可以做,但解析字符串不是SQL的優勢之一。

+0

感謝您的查詢。但計數Numberoflocations只返回1時,表中的位置超過一個 – Paulraj 2009-11-04 12:29:38

+0

對,我想我明白你的意思了。我會編輯答案。 – Andomar 2009-11-04 12:39:53

0

您應該在客戶端應用程序中執行此操作,而不是在數據庫上執行此操作。

當您進行SQL查詢時,您必須靜態指定想要獲取的列,即在執行結果集之前將結果集中需要的列告訴DB。例如,如果你有一個日期時間存儲,你可能會做一些像select month(birthday), select year(birthday) from ...,所以在這種情況下,我們拆分生日列2列,但它是在查詢中指定我們將有什麼列。

在你的情況,你就必須得到完全從數據庫US%UK%JAPAN%CANADA字符串,然後你在你的軟件後把它分解,即

/* get data from database */ 
/* ... */ 
$user_location = ... /* extract the field from the resultset */ 
$user_locations = explode("%", $user_location); 
0

這是一個不好的設計,如果你可以改變它,保存在2個表中的數據:

table users: id, name, surname ... 

table users_location: user_id (fk), location 

users_location將有thorugh USER_ID領域的外鍵的用戶

2

「正確的事」將會把這些位置拆分到另一張桌子上,並建立它們之間的多對多關係。

create table users (
    id int not null auto_increment primary key, 
    name varchar(64) 
) 

create table locations (
    id int not null auto_increment primary key, 
    name varchar(64) 
) 

create table users_locations (
    id int not null auto_increment primary key, 
    user_id int not null, 
    location_id int not null, 
    unique index user_location_unique_together (user_id, location_id) 
) 

然後,確保使用外鍵(和InnoDB引擎)或觸發器的引用完整性。

1

這應該這樣做

DELIMITER $$ 

DROP PROCEDURE IF EXISTS `CSV2LST`$$ 

CREATE DEFINER=`root`@`%` PROCEDURE `CSV2LST`(IN csv_ TEXT) 
BEGIN 

SET @s=CONCAT('select \"',REPLACE(csv_,',','\" union select \"'),'\";'); 
PREPARE stmt FROM @s; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 
END$$ 

DELIMITER ;