<tfoot id='d5x5C'></tfoot>

    <i id='d5x5C'><tr id='d5x5C'><dt id='d5x5C'><q id='d5x5C'><span id='d5x5C'><b id='d5x5C'><form id='d5x5C'><ins id='d5x5C'></ins><ul id='d5x5C'></ul><sub id='d5x5C'></sub></form><legend id='d5x5C'></legend><bdo id='d5x5C'><pre id='d5x5C'><center id='d5x5C'></center></pre></bdo></b><th id='d5x5C'></th></span></q></dt></tr></i><div id='d5x5C'><tfoot id='d5x5C'></tfoot><dl id='d5x5C'><fieldset id='d5x5C'></fieldset></dl></div>

    1. <legend id='d5x5C'><style id='d5x5C'><dir id='d5x5C'><q id='d5x5C'></q></dir></style></legend>
      • <bdo id='d5x5C'></bdo><ul id='d5x5C'></ul>

      <small id='d5x5C'></small><noframes id='d5x5C'>

      MYSQL - 将数据拆分为多行

      MYSQL - Split Data Into Multiple Rows(MYSQL - 将数据拆分为多行)
      • <i id='PnJOe'><tr id='PnJOe'><dt id='PnJOe'><q id='PnJOe'><span id='PnJOe'><b id='PnJOe'><form id='PnJOe'><ins id='PnJOe'></ins><ul id='PnJOe'></ul><sub id='PnJOe'></sub></form><legend id='PnJOe'></legend><bdo id='PnJOe'><pre id='PnJOe'><center id='PnJOe'></center></pre></bdo></b><th id='PnJOe'></th></span></q></dt></tr></i><div id='PnJOe'><tfoot id='PnJOe'></tfoot><dl id='PnJOe'><fieldset id='PnJOe'></fieldset></dl></div>
      • <small id='PnJOe'></small><noframes id='PnJOe'>

          <tbody id='PnJOe'></tbody>
        <tfoot id='PnJOe'></tfoot>

              <bdo id='PnJOe'></bdo><ul id='PnJOe'></ul>
              <legend id='PnJOe'><style id='PnJOe'><dir id='PnJOe'><q id='PnJOe'></q></dir></style></legend>
              1. 本文介绍了MYSQL - 将数据拆分为多行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                我使用从 IMDB 收集信息并将它们传输到 MYSQL 数据库的应用程序导入了一些数据.

                I have imported some data using an application that collects info from IMDB and transfers them into a MYSQL database.

                这些字段似乎没有被规范化并且在 1 个字段中包含许多值

                It seems the fields have not been normalized and contained many values within 1 field

                例如:

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

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

                Is there way to separate the values and have them inserted into another table to something like this and without any duplicates?

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

                我做了一些谷歌搜索,发现我应该使用 PHP 处理这些数据.但我对 PHP 一窍不通.

                I did some googling and found that I am supposed to process this data using PHP. But I have no knowledge with PHP at all.

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

                Is there anyway to convert this data using just MYSQL?

                推荐答案

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

                You can use a stored procedure which uses a cursor to solve this but it's not very elegant but neither is a comma separated list of writers !

                以下代码来自类似问题,但您最好彻底检查一下.

                Had the following code lying around from a similar question but you'd better check it thoroughly.

                希望有帮助:)

                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 ;
                

                编辑

                修改 sproc 使其不会跳过关键值!

                Amended sproc so that it doesnt skip key values !

                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 ;
                

                这篇关于MYSQL - 将数据拆分为多行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                相关文档推荐

                What does SQL clause quot;GROUP BY 1quot; mean?(SQL 子句“GROUP BY 1是什么意思?意思是?)
                MySQL groupwise MAX() returns unexpected results(MySQL groupwise MAX() 返回意外结果)
                MySQL SELECT most frequent by group(MySQL SELECT 按组最频繁)
                Why Mysql#39;s Group By and Oracle#39;s Group by behaviours are different(为什么 Mysql 的 Group By 和 Oracle 的 Group by 行为不同)
                MySQL GROUP BY DateTime +/- 3 seconds(MySQL GROUP BY DateTime +/- 3 秒)
                MySQL cumulative sum grouped by date(按日期分组的 MySQL 累计总和)
                    • <bdo id='rQnRH'></bdo><ul id='rQnRH'></ul>

                      1. <legend id='rQnRH'><style id='rQnRH'><dir id='rQnRH'><q id='rQnRH'></q></dir></style></legend>

                        <tfoot id='rQnRH'></tfoot>

                        <small id='rQnRH'></small><noframes id='rQnRH'>

                        <i id='rQnRH'><tr id='rQnRH'><dt id='rQnRH'><q id='rQnRH'><span id='rQnRH'><b id='rQnRH'><form id='rQnRH'><ins id='rQnRH'></ins><ul id='rQnRH'></ul><sub id='rQnRH'></sub></form><legend id='rQnRH'></legend><bdo id='rQnRH'><pre id='rQnRH'><center id='rQnRH'></center></pre></bdo></b><th id='rQnRH'></th></span></q></dt></tr></i><div id='rQnRH'><tfoot id='rQnRH'></tfoot><dl id='rQnRH'><fieldset id='rQnRH'></fieldset></dl></div>

                          <tbody id='rQnRH'></tbody>