如何从现有 table 创建 table

How to create table from an existing table

我在 Oracle APEX 中,想从其他现有的创建一个新的 table,如下所示:

我在 SONGS table 中有一列是:

ARTIST NAME Another header
Bad Bunny row
Bad Bunny, Ozuna, Daddy Yankee row

我想要另一个 table:

ID Artist
1 Bad Bunny
2 Ozuna
3 Daddy Yankee

此外,根据这 2 个 table,我想创建另一个 table 或关系来表明艺术家参与了哪些歌曲。

类似于:

Song ID Artist ID
1 1
2 1
2 2

我想让第三个table知道某位艺术家参与了哪首歌。

所以我无法从第一个 table 创建第二个和第三个 table。

这些实际上是一个问题中的 2 个不同问题。将它们视为 2 个不同的问题。

  1. 如何设计您的 table。这需要先完成,您可以稍后在其中导入数据。创建歌曲 table、艺术家 table 和交叉点 table (artist_songs),同时使用艺术家和歌曲的外键。它应该非常简单,网上有成千上万的示例,或者,由于您使用的是 apex,因此使用 quicksql (SQL WOrkshop > Utilities > quick sql) 生成tables 也是一个选项。
  2. 将数据从该基础 table 迁移到新的标准化 table 中。看看这个similar Whosebug question

关于您最初可用的数据,您提供的信息很少。它仅以逗号分隔的形式显示艺术家 - 很难说您将如何填充歌曲或将 table 与该信息相交。

您可以编写并执行如下过程:

create or replace procedure "P_SONG_PARSE"
is
my_artist VARCHAR2(4000);
my_artist_id NUMBER;
my_temp VARCHAR2(4000);
my_pos NUMBER;

begin
    for rs in (select * from songs)
    loop
        my_temp := rs.ARTIST_NAME;
        my_pos := 0;
        loop
            my_pos := instr(my_temp,',');
            if my_pos = 0 then
                my_artist := trim(my_temp);
            else
                my_artist := trim(substr(my_temp,1,my_pos-1));
            end if;
            begin
                select ID
                into my_artist_id 
                from ARTISTS
                where ARTIST = my_artist;
                exception 
                    when no_data_found then
                        begin
                            select nvl(max(ID),0) + 1
                              into my_artist_id
                              from ARTISTS;
                            insert into ARTISTS(ID,           Artist)
                                        values (my_artist_id, my_artist);
                        end;
            end; 
            insert into SONG_ARTISTS("Song ID", "Artist ID")
                              values(rs.ID,     my_artist_id);
            exit when my_pos = 0;
            my_temp := substr(my_temp,my_pos+1);
        end loop;
    end loop;    
end;