SQL拆分列并更新备用表

时间:2018-08-06 17:02:05

标签: sql oracle oracle-sqldeveloper

我正在处理几个不同的表,这些表由来自对电影评分的用户的数据组成。我的电影表当前列出了MovieId,MovieTitle和Category。每个类别列中的数据在每行中都有重复的组,我想通过将它们移到Movie类别(由MovieId,CategoryId组成)中来消除。

我的类别列使用|作为分隔符,例如“动作|惊悚|戏剧”。我有一个单独的表CategoryDe​​scription,为每个流派分配一个CategoryId,因此,例如,我希望最终的MovieCategories表看起来像这样:

 MovieId | CategoryId
------------------------
 1           1
 1           4
 1           7

,以此类推,分别针对每部电影及其各自的流派。任何帮助将不胜感激!

编辑:好的-期望的结果将是我上面的表格,其中列出了每部电影和每种类型。例如,假设我的电影表中有:

MovieId   |   MovieTitle    | Category
  1            Toy Story        Animated | Childrens
  2            Die Hard         Action | Thriller

我希望我的MovieCategories表具有MovieId和我的Categories表(列出了CategoryId 1-20和每种流派)中的相应CategoryId,所以我在上述数据的最终表中的结果将是

 MovieId     |   CategoryId
 1                  1
 1                  4
 2                  3
 2                  5

希望如此!

再进行一次编辑:

感谢到目前为止的评论。我能够查询到几乎产生想要的结果,但是现在如何更新我的MovieCategories表?这是有效的查询:

 select distinct
    DUMMYMOVIES.MovieId,
    trim(regexp_substr(DUMMYMOVIES.CatDescription, '[^|]+', 1, 
   levels.column_value)) as Category
  from 
    DUMMYMOVIES,
    table(cast(multiset(select level from dual connect by  level <= 
   length (regexp_replace(DUMMYMOVIES.CatDescription, '[^|]+'))  + 1) as 
   sys.OdciNumberList)) levels
  order by MovieId;

这样可以正确地拆分“类别”列,但是如何将其转移到“电影类别”表中?我可以使用UPDATE语句并让它运行此查询,对照我的CategoryDe​​scription表检查类别名称吗?

2 个答案:

答案 0 :(得分:0)

我创建了2个哑桌电影和类别。填充样本数据和所需的输出。

电影表创建:

create table movie
(
movie_id varchar2(200),
movie_title varchar2(100),
category varchar2(100)
);

insert into movie values (1,'Toy Story','Animated | Childrens');
insert into movie values (2,'Die Hard','Action | Thriller');

类别表的创建:

create table category
(
categoryid varchar2(100),
categoryname varchar2(100)
);


insert into category values (1,'Animated');
insert into category values (4,'Childrens');
insert into category values (3,'Action');
insert into category values (5,'Thriller');

主要查询:

select t1.movie_id,t2.CATEGORYID from
(
select distinct cat,movie_id from(
select trim(regexp_substr(category, '[^|]+', 1, LEVEL)) as cat,movie_id from movie  
CONNECT BY instr(category, '|', 1, LEVEL - 1) > 0)) t1
join
CATEGORY t2 on t1.cat = t2.categoryname;

希望这会有所帮助

答案 1 :(得分:0)

试图即兴创作(在后台尖叫着孩子)-提出解决方案(可能需要一些调整,但可能是一个很好的开始):

with tmp_tbl as(
  select
    1 MovieId,
    'Toy Story' MovieTitle,
    'Animated | Childrens' Category
  from dual
  union all
  select
    2 MovieId,
    'Die Hard' MovieTitle,
    'Action | Thrille' Category
  from dual
  union all
  select
    3 MovieId,
    'Beuty and the Beast' MovieTitle,
    'Musical | Comedy | Kids' Category
  from dual)
select
  tmp_out.movieid,
  tmp_out.MovieTitle,
  trim(tmp_out.category_splited)
from(
  select
    tmp.movieid,
    tmp.MovieTitle,
    regexp_substr(tmp.Category,'[^|]+', 1, level) category_splited
  from
    tmp_tbl tmp
  connect by
    regexp_substr(tmp.Category,'[^|]+', 1, level) is not null) tmp_out
group by
  tmp_out.movieid,
  tmp_out.MovieTitle,
  tmp_out.category_splited
order by
  tmp_out.movieid,
  tmp_out.category_splited

输出:

1   Toy Story             Animated
1   Toy Story             Childrens
2   Die Hard              Action
2   Die Hard              Thrille
3   Beuty and the Beast   Musical
3   Beuty and the Beast   Kids
3   Beuty and the Beast   Comedy