2016-09-03 8 views
0

私はPostgreSQLとPythonの新機能ですが、私は外来キーを理解する上で問題があります。私はhereからの例を見て持っていたが、私はそれは私が簡単な例としてPostgreSQL:既存のテーブルの新しいテーブルの外部キー

を必要とする正確に何であるとは思わない、私は既存のテーブルにいくつかの情報を持っている:

[ID  REFERENCE  REF_AGE DATA1  DATA 2] 
    [1  JOHN   50  50   60 ] 
    [2  JOHN   50  55   30 ] 
    [3  TOM   60  60   10 ] 
    [4  MATT   30  76   57 ] 
    [5  MATT   30  45   47 ] 

私が欲しいですこれから2つの新しいテーブルを作成します。 1つはIDとデータを含み、もう1つの新しいテーブルにリンクするreference_idが付いています。参照テーブル。各参照(たとえば、上記の年齢)に関するその他の情報を保存できます。

表1:

[ID  REF_ID  DATA1  DATA 2] 
    [1  1    50   60 ] 
    [2  1    55   30 ] 
    [3  2    60   10 ] 
    [4  3    76   57 ] 
    [5  3    45   47 ] 

表2:

[REF_ID  NAME AGE ] 
    [1   JOHN 50 ] 
    [2   TOM  60 ] 
    [3   MATT 30 ] 

誰がどのようにこのような既存のデータを分割するために私を見ることができますか?一意の値を元のテーブル参照列から新しい参照テーブルに区切り、対応するref_idを別の新しいテーブルに挿入しますか?

答えて

2

レシピがあります。しかし、人の名前が一意でない場合は、問題があります。個別のペアを選択する

drop table if exists not_normalized cascade; 
create table not_normalized (
    id int, reference text, ref_age int, data1 int, data2 int 
); 

insert into not_normalized (id, reference, ref_age, data1, data2) values 
(1,'JOHN',50,50, 60 ), 
(2,'JOHN',50,55, 30 ), 
(3,'TOM',60,60, 10 ), 
(4,'MATT',30,76, 57 ), 
(5,'MATT',30,45, 47 ), 
(6,null,null,42,50); 

drop table if exists referenced cascade; 
create table referenced (
    ref_id serial primary key, 
    name text, 
    age int 
); 

(名前、年齢)が名前の衝突の問題が最小限に抑え:

insert into referenced (name, age) 
select distinct reference, ref_age 
from not_normalized 
where (reference, ref_age) is not null 
; 
table referenced; 
reference | ref_age 
-----------+--------- 
JOHN  |  50 
TOM  |  60 
MATT  |  30 

drop table if exists referencer; 
create table referencer (
    id serial primary key, 
    ref_id int references referenced (ref_id), 
    data1 int, data2 int 
); 

を再び衝突を最小限に抑えるために年齢を使用します。

insert into referencer (ref_id, data1, data2) 
select r.ref_id, data1, data2 
from 
    not_normalized nn 
    left join 
    referenced r on r.name = nn.reference and r.age = nn.ref_age 
; 
table referencer; 
id | ref_id | data1 | data2 
----+--------+-------+------- 
    1 |  1 | 50 | 60 
    2 |  1 | 55 | 30 
    3 |  3 | 76 | 57 
    4 |  3 | 45 | 47 
    5 |  2 | 60 | 10 
    6 |  | 42 | 50 
+0

が、これはまさに私でしたありがとう必要!私は以来、別の問題になってきました。 not_normalizedにdata1とdata2が含まれているが参照(またはref_age)がない別の行を追加すると、これらの列はNULLになります。あなたはこれにどのように対処していますか? refercerの出力は、この行を完全に無視しているようですが、これはNULLと結合しようとしていることを前提としています。 – MattGeo

+0

@ user6789594「内部結合」を「外部結合」に変更します。更新された答え。 –

+0

申し訳ありませんが、私は本当に別の質問を作成したくありませんでした。私は名前が記入される場所にインスタンスを持ってきました。 'Peter'が、年齢はNULLになります。この場合に対処し、それにref_idを与える方法はありますか?参照されるテーブルの年齢はNULLになりますか?いずれかの列がnullの場合、(reference、ref_age)is not nullは常にNULLを返すようです。 – MattGeo

関連する問題