[英]Parsing a VARCHAR row by a delimiter and updating the table rows as such in Oracle SQL
我现在很难过。 我有一个看起来像下面的表格。
movieID | Genre
----------------------------
1 Action | Comedy
2 Drama
3 Action | Horror | Thriller
4 Comedy | Drama
5 Action | Suspense | Comedy
我需要将其转换为如下所示...
movieID | Genre
-----------------------------
1 Action
1 Comedy
2 Drama
3 Action
3 Horror
3 Thriller
4 Comedy
4 Drama
我一直在网上寻找所有人,似乎可以找到一些示例,这些示例将输出如下所示的数据。 但是,我想知道的是,是否有一种方法可以将表数据实际更新为如下所示? 不只是创建看起来像所需输出的查询,而无需更改表中存储的实际信息。
可能吗? 据我所知,似乎并非如此,也许我正在击败一头死马,试图找到解决这个问题的办法。
谢谢!
结合使用MERGE
语句和多种方法来分割定界字符串 :
Oracle 11g R2架构设置 :
create table movies ( movieID, Genre ) AS
SELECT 1, 'Action | Comedy' FROM DUAL UNION ALL
SELECT 2, 'Drama' FROM DUAL UNION ALL
SELECT 3, 'Action | Horror | Thriller' FROM DUAL UNION ALL
SELECT 4, 'Comedy | Drama' FROM DUAL UNION ALL
SELECT 5, 'Action | Suspense | Comedy' FROM DUAL;
查询1 :
MERGE INTO movies dst
USING (
WITH movie_genres ( rid, movieID, lvl, maxlvl, genre, all_genres ) AS (
SELECT ROWID rid,
movieID,
1,
REGEXP_COUNT( genre, '(.+?)(\s*\|\s*|$)' ),
REGEXP_SUBSTR( genre, '(.+?)(\s*\|\s*|$)', 1, 1, NULL, 1 ),
genre
FROM movies
UNION ALL
SELECT rid,
movieID,
lvl + 1,
maxlvl,
REGEXP_SUBSTR( all_genres, '(.+?)(\s*\|\s*|$)', 1, lvl + 1, NULL, 1 ),
all_genres
FROM movie_genres
WHERE lvl < maxlvl
)
SELECT rid, movieID, lvl, genre FROM movie_genres
) src
ON ( src.rid = dst.ROWID AND src.lvl = 1 )
WHEN MATCHED THEN
UPDATE SET genre = src.genre
WHEN NOT MATCHED THEN
INSERT ( movieID, genre ) VALUES ( src.movieID, src.genre )
查询2 :
SELECT * FROM movies ORDER BY movieId
结果 :
| MOVIEID | GENRE |
|---------|----------|
| 1 | Comedy |
| 1 | Action |
| 2 | Drama |
| 3 | Action |
| 3 | Horror |
| 3 | Thriller |
| 4 | Comedy |
| 4 | Drama |
| 5 | Suspense |
| 5 | Comedy |
| 5 | Action |
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.