2009-11-04 124 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 ;