2017-10-13 43 views
1
SELECT year, movietitle, director, actorname 
    FROM films11 
    WHERE actorname like '%Christina Ricci%' 
    order by year asc; 

元データスキーマから、ORACLE SQL Developerで次のようになります。Oracleテーブルでカンマ区切り値を複数の行に分割する方法

screenshot

私は、主キーがactor nameなるように、テーブル全体を変換したいです。

このように(第2表のように)クエリ

SELECT year, movietitle, director, actorname 
    FROM films11 
    WHERE actorname like '%Christina Ricci%' 
    order by year asc; 

は(新しいビューを作成する、または完全にデータスキーマを変更するのいずれか。)のみ検索項目を生成する(第3表)

+2

モニタを横向きにします – Strawberry

+0

あなたはすでにスクリーンショットで答えを得ています。あなたの新しいテーブルは、スクリーンショットの3番目の表に示すように、 'ACTORNAME'カラム内のすべての別個のアクタの行を持つ必要があります。代わりに、@Strawberryの提案を使用することもできます。 – JuveLeo1906

+0

テーブルの行数が多すぎます。あなたが新しい行に言ったように、 'ACTORNAME'カラムの名前をコンマで分割するSQLクエリがあるかどうか疑問に思っています。 – 2milli

答えて

0

ステップ1:から

を "データベースを爆破する方法":

SQL Fiddle

Oracleの11グラムR2スキーマのセットアップ

クエリ1

select * from films11 

Results

| YEAR | DIRECTOR | MOVIETITLE |  ACTORNAME | 
|------|----------|------------|----------------| 
| 2000 |  dir1 |  title1 |  act1,act2 | 
| 2001 |  dir2 |  title2 | act1,act2,act3 | 
| 2002 |  dir1 |  title3 |   act4 | 

クエリ2

素敵 直積
select YT.year, YT.movietitle, 
     REPLACE(REGEXP_SUBSTR(YT.actorname||',','.*?,',1,lvl.lvl),',','') AS actorname 
from films11 YT 
join (select level as lvl 
     from dual 
     connect by level <= (select max(regexp_count(actorname,',')+1) from films11) 
    ) lvl on lvl.lvl <= regexp_count(YT.actorname,',')+1 
    order by YT.year, YT.movietitle, actorname 

:あなたは ONCEそれを実行し、正規化されたDB


にすべてを移動するためにそれを使用

| YEAR | MOVIETITLE | ACTORNAME | 
|------|------------|-----------| 
| 2000 |  title1 |  act1 | 
| 2000 |  title1 |  act2 | 
| 2001 |  title2 |  act1 | 
| 2001 |  title2 |  act2 | 
| 2001 |  title2 |  act3 | 
| 2002 |  title3 |  act4 | 

Resultsここでは10

より便利なものにあなたのスキーマを変更するには、完全なスクリプトでは、ちょうどそのような選択することができます...その後

CREATE TABLE actors(
    id_actor NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY, 
    act_name VARCHAR2(100) 
) 
; 

CREATE TABLE directors(
    id_director NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY, 
    dir_name VARCHAR2(100) 
) 
; 

CREATE TABLE movies(
    id_movie NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY, 
    mov_year NUMBER, 
    mov_name VARCHAR2(100), 
    director_id NUMBER 
) 
; 

CREATE TABLE playedby(
    movie_id NUMBER, 
    actor_id NUMBER 
) 
; 

    INSERT INTO directors (dir_name) 
    SELECT DISTINCT director dir_name 
    FROM films11 
    ; 

    INSERT INTO movies (mov_year, mov_name, director_id) 
    SELECT year mov_year, movietitle mov_name, directors.id_director director_id 
    FROM films11 
    INNER JOIN directors ON directors.dir_name = films11.director 

    ; 

    INSERT INTO actors (act_name) 
    SELECT DISTINCT t.actorname act_name 
    FROM (
     SELECT YT.year, YT.movietitle, 
       REPLACE(REGEXP_SUBSTR(YT.actorname||',','.*?,',1,lvl.lvl),',','') AS actorname 
     FROM films11 YT 
     JOIN (SELECT level AS lvl 
       FROM dual 
       CONNECT BY level <= (SELECT MAX(REGEXP_COUNT(actorname,',')+1) FROM films11) 
      ) lvl ON lvl.lvl <= REGEXP_COUNT(YT.actorname,',')+1 
    ) t 
    ; 

    INSERT INTO playedby (movie_id, actor_id) 
    SELECT movies.id_movie movie_id, actors.id_actor actor_id 
    FROM (
     SELECT YT.year, YT.movietitle, 
       REPLACE(REGEXP_SUBSTR(YT.actorname||',','.*?,',1,lvl.lvl),',','') AS actorname 
     FROM films11 YT 
     JOIN (SELECT level AS lvl 
       FROM dual 
       CONNECT BY level <= (SELECT MAX(REGEXP_COUNT(actorname,',')+1) FROM films11) 
      ) lvl ON lvl.lvl <= REGEXP_COUNT(YT.actorname,',')+1 
    ) t 
    INNER JOIN actors ON t.actorname = actors.act_name 
    INNER JOIN movies ON t.year = movies.mov_year AND t.movietitle = movies.mov_name 

    ; 

です:

クエリ3

SELECT mov_year, mov_name, dir_name, act_name 
FROM movies 
INNER JOIN directors ON directors.id_director = movies.director_id 
INNER JOIN playedby ON movies.id_movie = playedby.movie_id 
INNER JOIN actors ON playedby.actor_id = actors.id_actor 
WHERE act_name like '%act2%' 
order by mov_year asc 

Results

| MOV_YEAR | MOV_NAME | DIR_NAME | ACT_NAME | 
|----------|----------|----------|----------| 
|  2000 | title1 |  dir1 |  act2 | 
|  2001 | title2 |  dir2 |  act2 | 
+0

**美しい**あなたの応答の後には非常に役立ちます。 [SQLFiddle]のWebサイト(http://sqlfiddle.com)は、私が今日学んだ次善のもののようです。 – 2milli

+0

@ 2milliよろしくお願いします;) – Blag

関連する問題