2017-05-26 141 views
0

我正在研究JDBC/Oracle SQL項目,並遇到了我認爲是我的最終問題。我有電影,其類別,上市的大表如下: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的結果而不是Hard Hard。請記住,我需要它來更新我的原始表格,而不僅僅是創建一個查詢。

SELECT distinct MovieId, MovieTitle,REGEXP_SUBSTR(Category,'[^|$]+', 1, LEVEL) Category 

FROM Categories 

CONNECT BY REGEXP_SUBSTR(Category, '[^|$]+', 1, LEVEL) IS NOT NULL; 

任何幫助表示讚賞。我已經瀏覽過其他線程,其中很多都是通過更小的數據表進行排序,而不是像我的那樣大。謝謝!

+0

你的谷歌搜索字符串是'多對多relationships.' –

回答

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和標題屬性的電影實體,以及具有描述標識和說明實體的屬性的流派實體。一部電影可以有很多流派,一部流派可以被許多電影使用,這是一種多對多的關係。爲了對它進行建模,您需要從每個實體的主鍵(唯一標識實體實例的屬性),並將它們組合爲外鍵,這些外鍵就是所謂的關聯表的主鍵。在這種情況下,我會稱之爲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 
+0

謝謝!這比我所擁有的要好得多。謝謝! – Polyphase29

+0

那麼我猜我的問題是,我如何讓我的原創電影數據庫中的流派與我的流派數據庫中的數字相對應? – Polyphase29

+0

對不起 - 重讀我意識到我的問題措辭很差。 由於我通過CSV文件將影片帶入,因此它們在使用分隔符分隔的數據庫上。我需要將每部電影的每種風格與genreId進行協調。我明白我可以使用外鍵關係做到這一點,但我只是有點無知,讓它們全部同步。感謝您的任何建議。 – Polyphase29

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

+0

這工作!非常感謝你。比我的方法更直接。 編輯 - 實際上是一件事。這會正確運行查詢,但是我可以用它來更新我的原始類別表? – Polyphase29

+1

您可以將ROWID添加到result_data(僅適用於每個第一行),然後使用* MERGE *更新您的原始表格 –