MYSQL - 将数据拆分为多行

2023-12-21

我使用一个应用程序导入了一些数据,该应用程序从 IMDB 收集信息并将其传输到 MYSQL 数据库中。

这些字段似乎尚未标准化,并且 1 个字段中包含许多值

例如:

Table Movie
MovieID          Movie_Title           Written_By
1                Movie1                Person1, Person2   
2                Movie2                Person3  
3                Movie3                Person4, Person2, Person6  

有没有办法将这些值分开并将它们插入到另一个表中,就像这样并且没有任何重复项?

Table Writers
WriterID         Written_By                MovieId      
1                Person1                   1
2                Person2                   1
3                Person3                   3

我做了一些谷歌搜索,发现我应该使用 PHP 处理这些数据。 但我对PHP一无所知。

有没有办法仅使用 MYSQL 来转换这些数据?


您可以使用使用游标的存储过程来解决此问题,但它不是很优雅,而且逗号分隔的作者列表也不是!

类似问题中存在以下代码,但您最好彻底检查它。

希望能帮助到你 :)

mysql> select * from movies_unf;
+---------+-------------+------------------------------------------------------+
| movieID | movie_title | written_by                                           |
+---------+-------------+------------------------------------------------------+
|       1 | movie1      | person1, person2                                     |
|       2 | movie2      | person3                                              |
|       3 | movie3      | person4, person2, person6                            |
|       4 | movie4      | person4, person4, person1, person2, person1,person8, |
|       5 | movie1      | person1, person2                                     |
+---------+-------------+------------------------------------------------------+
5 rows in set (0.00 sec)

call normalise_movies_unf();

mysql> select * from movies;
+----------+--------+
| movie_id | title  |
+----------+--------+
|        1 | movie1 |
|        2 | movie2 |
|        3 | movie3 |
|        4 | movie4 |
+----------+--------+
4 rows in set (0.00 sec)

mysql> select * from writers;
+-----------+---------+
| writer_id | name    |
+-----------+---------+
|         1 | person1 |
|         2 | person2 |
|         3 | person3 |
|         4 | person4 |
|         6 | person6 |
|        12 | person8 |
+-----------+---------+
6 rows in set (0.00 sec)

mysql> select * from movie_writers;
+----------+-----------+
| movie_id | writer_id |
+----------+-----------+
|        1 |         1 |
|        1 |         2 |
|        2 |         3 |
|        3 |         2 |
|        3 |         4 |
|        3 |         6 |
|        4 |         1 |
|        4 |         2 |
|        4 |         4 |
|        4 |        12 |
+----------+-----------+
10 rows in set (0.00 sec)

示例表

drop table if exists movies_unf;
create table movies_unf
(
movieID int unsigned not null primary key,
movie_title varchar(255) not null,
written_by varchar(1024) not null
)engine=innodb;

insert into movies_unf values 
(1,'movie1','person1, person2'),
(2,'movie2','person3'),
(3,'movie3','person4, person2, person6'),
(4,'movie4','person4, person4, person1, person2, person1,person8,'), -- dodgy writers
(5,'movie1','person1, person2'); -- dodgy movie

drop table if exists movies;
create table movies
(
movie_id int unsigned not null auto_increment primary key,
title varchar(255) unique not null
)engine=innodb;

drop table if exists writers;
create table writers
(
writer_id int unsigned not null auto_increment primary key,
name varchar(255) unique not null
)engine=innodb;

drop table if exists movie_writers;
create table movie_writers
(
movie_id int unsigned not null,
writer_id int unsigned not null,
primary key (movie_id, writer_id)
)engine=innodb;

存储过程

drop procedure if exists normalise_movies_unf;

delimiter #

create procedure normalise_movies_unf()
begin

declare v_movieID int unsigned default 0;
declare v_movie_title varchar(255);
declare v_writers varchar(1024);

declare v_movie_id int unsigned default 0;
declare v_writer_id int unsigned default 0;
declare v_name varchar(255);

declare v_csv_done tinyint unsigned default 0;
declare v_csv_idx int unsigned default 0;

declare v_done tinyint default 0;
declare v_cursor cursor for 
    select distinct movieID, movie_title, written_by from movies_unf;

declare continue handler for not found set v_done = 1;

start transaction;

open v_cursor;
repeat
  fetch v_cursor into v_movieID, v_movie_title, v_writers;

  set v_movie_title = trim(v_movie_title);
  set v_writers = replace(v_writers,' ', '');

  -- insert the movie
  insert ignore into movies (title) values (v_movie_title);
  select movie_id into v_movie_id from movies where title = v_movie_title;  

  -- split the out the writers and insert
  set v_csv_done = 0;       
  set v_csv_idx = 1;

  while not v_csv_done do
    set v_name = substring(v_writers, v_csv_idx, 
      if(locate(',', v_writers, v_csv_idx) > 0, 
        locate(',', v_writers, v_csv_idx) - v_csv_idx, 
        length(v_writers)));

      set v_name = trim(v_name);

      if length(v_name) > 0 then
        set v_csv_idx = v_csv_idx + length(v_name) + 1;

        insert ignore into writers (name) values (v_name);
        select writer_id into v_writer_id from writers where name = v_name; 
        insert ignore into movie_writers (movie_id, writer_id) values (v_movie_id, v_writer_id);
      else
        set v_csv_done = 1;
      end if;

  end while;

until v_done end repeat;
close v_cursor;

commit;

truncate table movies_unf;

end#

delimiter ;

EDIT

修改了存储过程,使其不会跳过键值!

drop procedure if exists normalise_movies_unf;

delimiter #

create procedure normalise_movies_unf()
begin

declare v_movieID int unsigned default 0;
declare v_movie_title varchar(255);
declare v_writers varchar(1024);

declare v_movie_id int unsigned default 0;
declare v_writer_id int unsigned default 0;
declare v_name varchar(255);

declare v_csv_done tinyint unsigned default 0;
declare v_csv_idx int unsigned default 0;

declare v_done tinyint default 0;
declare v_cursor cursor for 
    select distinct movieID, movie_title, written_by from movies_unf;

declare continue handler for not found set v_done = 1;

start transaction;

open v_cursor;
repeat
  fetch v_cursor into v_movieID, v_movie_title, v_writers;

  set v_movie_title = trim(v_movie_title);
  set v_writers = replace(v_writers,' ', '');

  -- insert the movie

  if not exists (select 1 from movies where title = v_movie_title) then
    insert ignore into movies (title) values (v_movie_title);
  end if;  
  select movie_id into v_movie_id from movies where title = v_movie_title;  

  -- split the out the writers and insert
  set v_csv_done = 0;       
  set v_csv_idx = 1;

  while not v_csv_done do
    set v_name = substring(v_writers, v_csv_idx, 
      if(locate(',', v_writers, v_csv_idx) > 0, 
        locate(',', v_writers, v_csv_idx) - v_csv_idx, 
        length(v_writers)));

      set v_name = trim(v_name);

      if length(v_name) > 0 then
        set v_csv_idx = v_csv_idx + length(v_name) + 1;


        if not exists (select 1 from writers where name = v_name) then
          insert ignore into writers (name) values (v_name);
        end if;
        select writer_id into v_writer_id from writers where name = v_name; 
        insert ignore into movie_writers (movie_id, writer_id) values (v_movie_id, v_writer_id);
      else
        set v_csv_done = 1;
      end if;

  end while;

until v_done end repeat;
close v_cursor;

commit;

truncate table movies_unf;

end#

delimiter ;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MYSQL - 将数据拆分为多行 的相关文章

  • MySQL集群启动失败

    这不是我第一次创建ndbcluster 但我没有收到这样的问题 我正在关注本手册 https hub docker com r mysql mysql cluster by mysql团队 我正在使用回显的默认配置在此 GitHub 存储库
  • 猪的组连接等效吗?

    试图在 Pig 上完成这个任务 寻找 MySQL 的 group concat 等效项 例如 在我的表中 我有以下内容 3fields userid clickcount pagenumber 155 2 12 155 3 133 155
  • 在MySQL中生成随机字符串

    我正在尝试使用函数在 phpmyadmin 中获取随机字符串 我有以下代码 CREATE FUNCTION randomPassword RETURNS varchar 128 BEGIN SET chars ABCDEFGHIJKLMNO
  • 如何使用 Mysql Python 连接器检索二进制数据?

    如果我在 MySQL 中创建一个包含二进制数据的简单表 CREATE TABLE foo bar binary 4 INSERT INTO foo bar VALUES UNHEX de12 然后尝试使用 MySQL Connector P
  • MySQL 左连接 WHERE table2.field = "X"

    我有以下表格 pages Field Type Null Key Default Extra page id int 11 NO PRI NULL auto increment type varchar 20 NO NULL
  • mysql-connector-c++ - “get_driver_instance”不是“sql::mysql”的成员

    我是 C 的初学者 我认为学习的唯一方法就是接触一些代码 我正在尝试构建一个连接到 mysql 数据库的程序 我在 Linux 上使用 g 没有想法 我运行 make 这是我的错误 hello cpp 38 error get driver
  • 使用“INSERT ... ON DUPLICATE KEY UPDATE”插入多条记录

    我的表结构 table marks 我的目标 我想用条件插入或更新多条记录 我目前正在通过此查询进行检查 第一步 SELECT FROM marks WHERE student 115 AND param 1 第二步 if records
  • MySQL 和 PHP 参数 1 作为资源

    好吧 当我运行下面提到的代码时 PHP 向我抛出此错误 在日志中 Error mysql num rows 期望参数 1 为资源 第 10 行 place 中给出的字符串 9 11号线 queryFP SELECT FROM db coun
  • MySql 视图脚本中的注释

    可以这样做吗 我尝试过多个 gui mysql workbench navicat toad for mysql 但没有一个保存这样的注释 something important select something else importan
  • “修改列”与“更改列”

    我知道 我们不能使用重命名列MODIFY COLUMN语法 但我们可以使用CHANGE COLUMN syntax 我的问题是 主要用途是什么modify syntax 例如 ALATER TABLE tablename CHANGE co
  • 如何从表中检索特定列 --- JPA 或 CrudRepository?我只想从用户表中检索电子邮件列

    用户模型 Entity Table name user uniqueConstraints UniqueConstraint columnNames email public class User implements Serializab
  • MySQL 概念:会话与连接

    我对 MySQL 的概念有点困惑 会话与连接 当谈论连接到 MySQL 时 我们使用连接术语 连接池等 然而在 MySQL 在线文档中 http dev mysql com doc refman 4 1 en server system v
  • 使用用户定义函数 MySql 时出错

    您好 请帮我解决这个问题 提前致谢 我在数据库中定义了这些函数 CREATE FUNCTION levenshtein s1 VARCHAR 255 s2 VARCHAR 255 RETURNS INT DETERMINISTIC BEGI
  • 休眠以持久保存日期

    有没有办法告诉 Hibernate java util Date 应该持久保存 我需要这个来解决 MySQL 中缺少的毫秒分辨率问题 您能想到这种方法有什么缺点吗 您可以自己创建字段long 或者使用自定义的UserType 实施后User
  • 防止 Propel 插入空字符串

    当未设置列时 如何防止 Propel ORM 插入空字符串 CREATE TABLE user uid INTEGER PRIMARY KEY AUTO INCREMENT email VARCHAR 255 NOT NULL UNIQUE
  • 如何使用 MySQL 选择有特定值的 2 个连续行?

    我正在构建一个系统 该系统应该显示学生何时连续缺席两天 例如 此表包含缺勤情况 day id missed 2016 10 6 1 true 2016 10 6 2 true 2016 10 6 3 false 2016 10 7 1 tr
  • 来自数据库的 jfreechart 散点图

    如何使用java中的jfreechart绘制mysql数据库表中数据的散点图 我使用过 Swing 库 任何链接都会有帮助 我搜索了谷歌但找不到理解的解决方案 如果您有代码 请提供给我 实际上我确实做了条形图并使用 jfreechart 绘
  • 使用函数的 SQL 查询 - 如何获取列表的最大计数

    如何查询 MAXIMUM COUNT 交易次数 我的代码如下 SELECT customer id COUNT customer id FROM rental GROUP BY customer id HAVING MAX COUNT cu
  • 选择获取与 MySQL Group 中 max 对应的整行

    当我使用Max使用后查找特定 MySQL 组中字段的最大值GROUP BY 是否可以获取包含最大值的整行 我在处理一些论坛代码时偶然发现了这个线程 我想获取每个线程的最新帖子并将其显示在特定板的线程列表中 Quassnoi上面的回答对我非常
  • 使用 PHP 将 latin1_swedish_ci 转换为 utf8

    我有一个数据库 里面充满了类似的值 Dhaka 应该是 Dhaka 因为我在创建数据库时没有指定排序规则 现在我想修复它 我无法从最初获取数据的地方再次获取数据 所以我在想是否可以在 php 脚本中获取数据并将其转换为正确的字符 我已将数据

随机推荐

  • FluentValidation Autofac ValidatorFactory

    我需要能够提供IComponentContext to my ValidatorFactory解决 FluentValidation 验证器 我有点卡住了 验证器工厂 public class ValidatorFactory Valida
  • numpy IndexError:当用另一个矩阵索引矩阵时,数组索引太多

    我有一个这样创建的矩阵 gt gt gt a np matrix 1 2 3 4 5 6 7 8 9 10 11 12 我有一个我创建的矩阵标签 如下所示 gt gt gt labels np matrix 1 0 1 1 这两个矩阵如下所
  • 如何将应用程序窗口托管为属于另一个进程的窗口的子窗口?

    我想将一个应用程序窗口从进程 A 托管到进程 B 的主窗口中 就像 A 的窗口是 MDI 子窗口一样 这在 Windows 中可能吗 还是有一些技巧可以让我伪造这个 顺便说一句 当 A 窗口嵌入到 B 窗口中时 我想删除 A 窗口的标题栏
  • 添加多个UIWindow

    我在另一个 UIWIndow 上添加一个新的 UIWIndow 以显示视图 但它没有显示任何内容 并且屏幕变得有点模糊 这是代码 UIWindow topWindow UIWindow alloc initWithFrame UIScree
  • Java 反映方法作用域变量

    使用反射 您几乎可以获得与类相关的所有内容 您可以获得所有声明的方法 字段和类 甚至可能更多 但我找不到反映方法的方法 因此我可以找出该方法可能使用的类 本质上我想找出给定类所具有的对其他类的所有依赖关系 例子 给出以下代码 import
  • MFMailComposeViewController:取消不会退出到我的应用程序?

    我正在尝试使用 MFMailComposeViewController 发送邮件 当我单击应用程序上的按钮时就会发生这种情况 当然 当我单击邮件控制器的取消按钮时 我想返回到我的应用程序视图 但它不起作用 该怎么办 这是我的代码 MFMai
  • 无法使用docker访问Web服务器

    我使用以下命令来运行容器 docker run p 3333 3333 d maill node web app 这是 docker ps 的结果 CONTAINER ID IMAGE COMMAND CREATED STATUS PORT
  • 如何在 NetBeans 中添加 JAR

    假设您创建了一个新项目 并希望它使用一些第三方库 例如 widget jar 在哪里添加这个 JAR 文件 gt gt 项目属性 gt gt 库 gt gt 编译时库 or 文件 gt gt 项目属性 gt gt 库 gt gt 运行时库
  • 是否可以在 Wildfly 中将数据源部署描述符与驱动程序模块一起使用?

    我无法使用 ds xml 部署描述符以及作为模块安装的数据库驱动程序来配置我的数据源 仅当我将数据库驱动程序直接部署为 jar 时 数据源 ds xml 文件才有效 我认为如果您选择将驱动程序安装为模块 则必须直接在standalone x
  • Visual Studio 调试器突出显示多行,而不仅仅是当前行

    这里有一个奇怪的人 当我尝试单步调试时 我全新安装的 Visual Studio 2017 版本 15 6 7 显示多行黄色 如下所示 它似乎指向它所在的正确行 但也指向它下面的其他几行 也许这与缩进或范围有关 我不确定 但当我进行结对编程
  • 有没有办法在 .NET 运行时中预分配堆,就像 Java 中的 -Xmx/-Xms 一样?

    在大多数平台和大多数 JVM 上 您可以通过将 Xmx 和 Xms 选项 或其变体 设置为相同大小来在启动时预分配堆 是否可以对 NET 执行相同的操作 如果可以 如何执行 遗憾的是 事实并非如此 NET 运行时为您做出有关堆大小和相对分代
  • 节点 --max_old_space_size 不起作用

    节点版本 6 9 x 我的申请给了我FATAL ERROR CALL AND RETRY LAST Allocation failed JavaScript heap out of memory error 所以我尝试使用更改内存分配max
  • 最大高度的子级:100% 溢出父级

    我试图了解对我来说似乎出乎意料的行为 我在容器内有一个最大高度为 100 的元素 该元素也使用了最大高度 但出乎意料的是 子元素溢出了父元素 container background blue padding 10px max height
  • 多行 WPF FormattedText 中特定字符的坐标

    如何获取多行 WPF FormattedText 中特定字符的位置 x y 坐标 我的文本可能包含斜体部分 粗体部分 不同字体 不同字体大小 不同对齐方式等 并且我需要获取第 30 个字符 可能位于第 3 行 的坐标 通过使用我可以从 Fo
  • 在 onclick 中声明一个变量?

    当有人点击某个东西然后声明一个变量时 如何在 JavaScript 中声明一个 var 具体取决于函数将返回的内容 即 true 或 false 值 就像是 onclick var varable somefunction 然后我将比较 o
  • PyDev 控制台工作目录

    当我打开 PyDev 控制台时 当前工作目录是我的 Eclipse 文件夹 如何配置控制台以使用项目文件夹作为当前工作目录 可以在工作区范围内设置吗 这个问题 https stackoverflow com questions 103199
  • Drupal:添加新节点时自动添加菜单项

    在Drupal中向页面添加节点时可以自动添加菜单项吗 换句话说 我可以将菜单父级与节点内容类型相关联 然后在添加新节点时自动添加子级吗 thanks 您可以使用 Drupal 7 上的规则来完成此操作 该模块 http drupal org
  • 为什么“删除[][]...多维数组;” C++中不存在运算符

    我一直想知道标准C 语言中是否有删除多维数组的运算符 如果我们创建了一个指向一维数组的指针 int array new int size 删除看起来像 delete array 那太棒了 但是如果我们有二维数组 我们就不能这样做 delet
  • python导入语句

    我已经开始使用 Python 大约一个月了 我遇到了一些我想更好地理解的事情 跟进口有关系 所以我有一个模块 根 核心 连接性 现在在这个模块中我定义了一个类 Connectivity 该模块还有一个 main 仅用于测试目的 不确定这是否
  • MYSQL - 将数据拆分为多行

    我使用一个应用程序导入了一些数据 该应用程序从 IMDB 收集信息并将其传输到 MYSQL 数据库中 这些字段似乎尚未标准化 并且 1 个字段中包含许多值 例如 Table Movie MovieID Movie Title Written