繁体   English   中英

如何在mysql中将单行拆分为多列

[英]How to split a single row in to multiple columns in mysql

简单地问,mysql中是否有任何功能可将单行元素拆分为多列? 我有一个表行,其中包含用户名,用户名user_id, user_name, user_location.

这样,用户可以添加多个位置。 我使用的是内插位置并将其存储在表格中作为一行。

当我在网格视图中显示用户记录时,由于通过拆分user_locations显示记录,因此出现了分页问题。 因此,我需要将user_locations(单行拆分为多列)。

mysql中是否有可用的功能来按字符(%)拆分和计数记录。

例如,user_location具有US%UK%JAPAN%CANADA

我如何将该记录分为4列。 我还需要检查计数值(4)。 提前致谢。

首先对字符串进行规范化,删除空位置,并确保末尾有%:

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 ,将输出:

LocationCount  Loc1    Loc2    Loc3
4              US      UK      JAPAN

因此,您可以看到它可以完成,但是解析字符串并不是SQL的强项之一。

“正确的事情”是将位置拆分到另一个表,并在它们之间建立多对多关系。

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引擎)或触发器确保引用完整性。

这应该做

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 ;

您应该在客户端应用程序而不是数据库中执行此操作。

进行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);

这是一个糟糕的设计,如果可以更改,请将数据存储在2个表中:

table users: id, name, surname ...

table users_location: user_id (fk), location

users_location将通过用户user_id字段为用户提供外键

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM