我正在研究JDBC / Oracle SQL项目,并且遇到了我认为最后的问题。我有一张大型电影及其类别表,如下所示:
Table name = Categories
MovieId MovieTitle Category
1 Die Hard Action|Drama
2 GoodFellas Drama|Crime
我试图让它看起来像这样:
MovieId MovieTitle Category
1 Die Hard Action
1 Die Hard Drama
2 Goodfellas Drama
2 Goodfellas Crime
这是我一直在玩的一般想法。当我在我的大桌子上运行它似乎无休止地运行时,我在一个较小的桌子上测试它并且它做了我想要的,但是它只显示了Goodfellas的结果而不是Die Hard。请记住,我需要它来更新我的原始表,而不仅仅是创建一个查询。
SELECT distinct MovieId, MovieTitle,REGEXP_SUBSTR(Category,'[^|$]+', 1, LEVEL) Category
FROM Categories
CONNECT BY REGEXP_SUBSTR(Category, '[^|$]+', 1, LEVEL) IS NOT NULL;
感谢任何帮助。我已经浏览了SO上的其他线程,其中很多都处理通过较小的数据表进行排序,而不是像我的那样大。谢谢!
答案 0 :(得分:2)
您可以在没有正则表达式的情况下尝试递归CTE
WITH result_data (MovieId, MovieTitle, Category, StartPosition, EndPosition)
AS (SELECT MovieId,
MovieTitle,
Category,
1,
INSTR(Category, '|')
FROM Categories
UNION ALL
SELECT MovieId,
MovieTitle,
Category,
EndPosition + 1,
INSTR(Category, '|', EndPosition + 1)
FROM result_data
WHERE EndPosition > 0)
SELECT MovieId,
MovieTitle,
SUBSTR(Category, StartPosition,
DECODE(EndPosition, 0, LENGTH(Category) + 1, EndPosition) - StartPosition) AS Category
FROM result_data
ORDER BY MovieId, StartPosition
您可以查看演示here
答案 1 :(得分:1)
这是另一种方式。而不是更新,为什么不截断表并重新加载它?
SQL> with Movie(id,title,genre) as (
select 1, 'Die Hard', 'Action|Drama' from dual union
select 2, 'GoodFellas', 'Drama|Crime' from dual
)
SELECT Id, title, --column_value substring_nbr,
regexp_substr(genre, '(.*?)(\||$)', 1, column_value, null, 1) genre
FROM category,
TABLE(
CAST(
MULTISET(SELECT LEVEL
FROM dual
CONNECT BY LEVEL <= REGEXP_COUNT(genre, '\|')+1
) AS sys.OdciNumberList
)
)
ORDER BY Id, title --, substring_nbr
;
ID TITLE GENRE
---------- ---------- ------------
1 Die Hard Action
1 Die Hard Drama
2 GoodFellas Drama
2 GoodFellas Crime
SQL>
虽然这回答了你的问题,但它不是一个好的数据库设计。我们退一步吧。您有一个具有ID和Title属性的Movie实体,以及一个具有描述ID和描述实体的属性的Genre实体。电影可以有许多类型,许多电影都可以使用一种类型,因此这是一种多对多的关系。为了对其进行建模,您可以从每个实体中获取主键(唯一标识实体实例的属性),并将它们作为外键一起作为所谓的关联表的主键。在这种情况下,我称之为movie_genre。因此,对于您的测试数据,我将使用3个表格对此进行建模:
Movie Genre Movie_Genre
----- ----- -----------
movieID TITLE genreID DESC movieID genreID
1 Die Hard 1 Action 1 1
2 GoodFellas 2 Drama 1 2
3 Crime 2 2
2 2