简体   繁体   English

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

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

Simply Asking, Is there any function available in mysql to split single row elements in to multiple columns ? 简单地问,mysql中是否有任何功能可将单行元素拆分为多列? I have a table row with the fields, user_id, user_name, user_location. 我有一个表行,其中包含用户名,用户名user_id, user_name, user_location.

In this a user can add multiple locations. 这样,用户可以添加多个位置。 I am imploding the locations and storing it in a table as a single row using php. 我使用的是内插位置并将其存储在表格中作为一行。

When i am showing the user records in a grid view, I am getting problem for pagination as i am showing the records by splitting the user_locations. 当我在网格视图中显示用户记录时,由于通过拆分user_locations显示记录,因此出现了分页问题。 So I need to split the user_locations ( single row to multiple columns). 因此,我需要将user_locations(单行拆分为多列)。

Is there any function available in mysql to split and count the records by character ( % ). mysql中是否有可用的功能来按字符(%)拆分和计数记录。

For Example the user_location having US%UK%JAPAN%CANADA 例如,user_location具有US%UK%JAPAN%CANADA

How can i split this record in to 4 columns. 我如何将该记录分为4列。 I need to check for the count values (4) also. 我还需要检查计数值(4)。 thanks in advance. 提前致谢。

First normalize the string, removing empty locations and making sure there's a % at the end: 首先对字符串进行规范化,删除空位置,并确保末尾有%:

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

Then we can count the number of entries with a trick. 然后,我们可以用技巧来计算条目数。 Replace '%' with '% ', and count the number of spaces added to the string. 将“%”替换为“%”,然后计算添加到字符串的空格数。 For example: 例如:

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

Using substring_index, we can add columns for a number of locations: 使用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

For your example US%UK%JAPAN%CANADA , this prints: 对于您的示例US%UK%JAPAN%CANADA ,将输出:

LocationCount  Loc1    Loc2    Loc3
4              US      UK      JAPAN

So you see it can be done, but parsing strings isn't one of SQL's strengths. 因此,您可以看到它可以完成,但是解析字符串并不是SQL的强项之一。

The "right thing" would be splitting the locations off to another table and establish a many-to-many relationship between them. “正确的事情”是将位置拆分到另一个表,并在它们之间建立多对多关系。

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)
)

Then, ensure referential integrity either using foreign keys (and InnoDB engine) or triggers. 然后,使用外键(和InnoDB引擎)或触发器确保引用完整性。

this should do it 这应该做

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 ;

You should do this in your client application, not on the database. 您应该在客户端应用程序而不是数据库中执行此操作。

When you make a SQL query you must statically specify the columns you want to get, that is, you tell the DB the columns you want in your resultset BEFORE executing it. 进行SQL查询时,必须静态指定要获取的列,即在执行结果之前,将结果集中的DB告诉数据库。 For instance, if you have a datetime stored, you may do something like select month(birthday), select year(birthday) from ... , so in this case we split the column birthday into 2 other columns, but it is specified in the query what columns we will have. 例如,如果您存储了一个日期时间 ,则可以执行诸如select month(birthday), select year(birthday) from ... ,因此在这种情况下,我们将生日列分割为另外2列,但在查询我们将拥有哪些列。

In your case, you would have to get exactly that US%UK%JAPAN%CANADA string from the database, and then you split it later in your software, ie 在您的情况下,您必须从数据库中准确获取US%UK%JAPAN%CANADA字符串,然后稍后在软件中将其拆分,即

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

This is a bad design, If you can change it, store the data in 2 tables: 这是一个糟糕的设计,如果可以更改,请将数据存储在2个表中:

table users: id, name, surname ...

table users_location: user_id (fk), location

users_location would have a foreign key to users thorugh user_id field users_location将通过用户user_id字段为用户提供外键

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

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