【问题标题】:Parsing a VARCHAR row by a delimiter and updating the table rows as such in Oracle SQL通过分隔符解析 VARCHAR 行并在 Oracle SQL 中更新表行
【发布时间】:2019-01-12 06:35:21
【问题描述】:

我对此感到非常困难。我有一个如下所示的表格。

    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

我一直在网上环顾每个人,我似乎只能找到一些查询示例,这些查询将输出如下所示的数据。但是,我想知道是否有一种方法可以实际更新表数据,使其看起来像这样?不仅仅是创建一个看起来像所需输出的查询,而不更改存储在表中的实际信息。

有可能吗?据我所知,它似乎不是这样,也许我正在拼命寻找解决这个问题的方法。

谢谢!

【问题讨论】:

    标签: sql oracle parsing split substring


    【解决方案1】:

    MERGE 语句与many ways to split delimited strings 中的任何一个一起使用:

    SQL Fiddle

    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
    

    Results

    | MOVIEID |    GENRE |
    |---------|----------|
    |       1 |   Comedy |
    |       1 |   Action |
    |       2 |    Drama |
    |       3 |   Action |
    |       3 |   Horror |
    |       3 | Thriller |
    |       4 |   Comedy |
    |       4 |    Drama |
    |       5 | Suspense |
    |       5 |   Comedy |
    |       5 |   Action |
    

    【讨论】:

    • 谢谢。这非常有效!如果您不介意,我有一个后续问题。是否可以将这个操作作为一个过程来执行?
    • @KevinGombos 是的,可以将其包装在一个过程中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-07
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 2013-03-04
    • 2016-07-30
    • 1970-01-01
    相关资源
    最近更新 更多