2016-08-03 3 views
2

私はすべての組織に1人の新しいユーザーを追加する必要があるPostgresで移行を構築しています。2つのテーブルのデータを使用してリレーションシップを構築するにはどうすればよいですか?

私は木のテーブルを持っていると仮定すると:

  • ユーザー
  • 組織
  • user_org

や団体のリストには、すでにDBに存在しています。

今、私は他のユーザーとそのような修正されたデータに基づいて、新しいユーザーを作成しています:私は今、必要なもの

insert into users 
select 
    ... 
from users where ... 
returning id 

は1つの組織にすべてのユーザーを関連付けることである(作成されたユーザとORGSの数字の数を想定しマッチング)。

cross joinは、すべてのユーザーをすべての組織に関連付けるので機能しません。

私はすでに組織に関連付けられているからコピーしているユーザーのリストは、新しく作成されたユーザーが異なるキーを持っているので、それに基づいて私のクエリを簡単に構築できますか?

+0

必ず私は完全にあなたの質問を理解していません。 10個の組織があると仮定すると、各組織に1人ずつ、10人のユーザーを挿入しますか?おそらくサンプルデータと期待される結果が役立つでしょう。 – sgeddes

+0

@sgeddes Correct –

+0

Postgresのバージョンとテーブルの定義が大きくなります。 –

答えて

2

私が正しく理解していない場合、ここinner joinを使用して1つのオプションだし、その後にjoinにテーブルごとにrow_numberを確立:

insert into user_org 
select u.id, o.id 
from (select id, row_number() over (order by id) rn 
     from usr) u join 
    (select id, row_number() over (order by id) rn 
     from org) o on u.rn = o.rn 
+0

私はそれを試します –

+0

それは私が必要なものを行うように見えます、私はいくつかのより多くのテストを行い、返信します。ありがとう! –

+0

両方のサブクエリで 'order by id'を使うには、' usr.id'と 'org.id'の* values *が同期している必要があります。これはほとんど想定されていません。確かに質問の情報に基づいていません。通常、このクエリは機能しません。 –

0

のリストを私が既にorgに関連付けられているからコピーしているユーザーは、それに基づいてクエリを作成する簡単な方法です。別の鍵?

PKなしで一意のユーザーを識別するための列のサブセットがある場合は、データ変更用のCTEを持つ安全なソリューションがあります。あなたも、一度に複数のユーザーのコピーを挿入することもできます

テンプレートのユーザーに参加する列の信頼性の高いセットを持つべきではない可能性は低い場合には

@sgeddes already suggestedのように、行番号を追加しますが、中実際に動作するクエリ:

WITH template_usr AS (
    SELECT u.*, uo.org_id -- include the connected org_id 
      row_number() OVER() AS rn -- arbitrary number 
    FROM usr  u 
    JOIN usr_org uo ON uo.usr_id = u.id -- guessing column names 
    WHERE ... -- make sure exactly *one* desired org is joined 
    ) 
, ins_usr AS (
    INSERT INTO usr u (...) -- add target columns 
    SELECT ... 
    FROM template_usr 
    ORDER BY rn    -- insert in same order! 
    RETURNING id 
    ) 
INSERT INTO usr_org (usr_id, org_id) 
SELECT iu.id, tu.org_id 
FROM (
    SELECT id, row_number() OVER (ORDER BY id) AS rn 
    FROM ins_usr 
    ) iu 
JOIN template_usr tu USING (rn) 
RETURNING *; -- optional 

関連:

関連する問題