【问题标题】:Split string into multiple rows in SQL在 SQL 中将字符串拆分为多行
【发布时间】:2012-02-03 06:04:42
【问题描述】:

我继承了一个数据库,在努力让它更干净、更有用的过程中,我遇到了以下问题。

将文件列移动到单独的表后,我现在的任务是将这些文件分成不同的行。请参阅下面的示例。

key | jobid       | files                  |
--------------------------------------------
1     30012        file1.pdf;file2.pdf
2     30013        file3.pdf
3     30014        file4.pdf;file5.pdf;file6.pdf

我想要一个 SQL 语句,它将表格变成如下:

key | jobid       | files                  |
--------------------------------------------
1     30012        file1.pdf
2     30013        file3.pdf
3     30014        file4.pdf
4     30012        file2.pdf
5     30014        file5.pdf
6     30014        file6.pdf

是否必须删除原始条目才能实现这一点并不重要,因此以下解决方案也可以接受:

key | jobid       | files                  |
--------------------------------------------
4     30012        file1.pdf
5     30013        file3.pdf
6     30014        file4.pdf
7     30012        file2.pdf
8     30014        file5.pdf
9     30014        file6.pdf

基本上我只需要在 ; 上拆分文件字符串。分隔符和使用拆分字符串创建的新行。

如果您能提供任何帮助,我们将不胜感激。

【问题讨论】:

  • 我理解这是一份一次性工作——对吗?
  • Mysql string split的可能重复
  • 是的,Eugen 是一次性工作。

标签: mysql sql


【解决方案1】:

在 PHP 中(假设 $db 是一个有效的数据库连接,key 是 auto_increment):

$sql="select `key`, jobid, files from filestable where files like '%\\;%'";
$qry=mysql_query($sql,$db);

$sql=array();
while (true) {
  $row=mysql_fetch_row($qry);
  if (!$row) break;

  $key=$row[0];
  $jobid=$row[1];
  $files=explode(';',$row[2]);
  foreach ($files as $file) {
    $file=mysql_real_escape_string($file,$db);
    $sql[]="insert into filestable (jobid,files) values ($jobid,'$file')";
  }
  $sql[]="delete from filestables where `key`=$key";
}

现在 $sql 有一组 SQL 语句要运行 - 要么在 while 循环结束时运行它们,要么将它们批量化,写出来以备后用,只要适合你的加载模式。

【讨论】:

  • 除了在 SQL 语句中添加通配符并在插入行中添加 " 之外,这非常有效。非常感谢!
  • 很好,我更正了缺少的引号和通配符,对此感到抱歉,这是“在输入第 n 行时考虑第 n+1 行”的坏情况
  • 问题是如何在SQL中做到这一点。
【解决方案2】:

我有完全相同的问题,找到了一篇可能有帮助的文章,他们提供了 MySQL 脚本

create table books (tags varchar(1000));

insert into books values
    ('A, B, C, D'),
    ('D, E'),
    ('F'),
    ('G, G, H')
;

select
  TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(B.tags, ',', NS.n), ',', -1)) as tag
from (
  select 1 as n union all
  select 2 union all
  select 3 union all
  select 4 union all
  select 5 union all
  select 6 union all
  select 7 union all
  select 8 union all
  select 9 union all
  select 10
) NS
inner join books B ON NS.n <= CHAR_LENGTH(B.tags) - CHAR_LENGTH(REPLACE(B.tags, ',', '')) + 1

我已在此处将键名添加到游乐场
https://www.db-fiddle.com/f/kLeLYVPmuoFtLEuAb8ihuE/0

参考:
https://www.holistics.io/blog/splitting-array-string-into-rows-in-amazon-redshift-or-mysql/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-31
    • 2014-12-12
    • 2016-04-18
    • 2017-04-25
    • 2013-02-12
    • 2021-11-17
    相关资源
    最近更新 更多