0

Oracle DB で 1 つの一括更新を実行する際に問題が発生しています。

マップと呼べるマッピングテーブルに一括挿入したい

データを取得する必要がある他の 2 つのテーブルがあります。最初のテーブルは、このクエリで挿入する目的のアカウントを選択できるアカウントテーブルです。

select account_id
from account
where company_id in (
select company_id
from company
where company_name = 'string');

このクエリは、挿入する会社名に応じてすべてのアカウントを選択します。

次に、グループを呼び出すことができるテーブルがあり、このテーブルには挿入した正確な数のグループがあり、グループには UID があるため、group_id は 1 から 500 です。

私がしなければならないことは次のとおりです。アカウントとグループの間の UID マッピングをテーブル マップに挿入する必要があります。実行する必要がある特別な順序はありません

insert into map (account_id, group_id) 
  values (number,number);

しかし、残念ながら、複数の結果を含む選択でそのような一括挿入を行う方法と、ループをカウントする方法がわかりません。

だから私の考えは、次のようなことです:

insert into map (account_id, group_id) values ((select account_id
from account
where company_id in (
select company_id
from company
where company_name = 'string')),loop from 1 to 500);

多くのgroup_idで挿入できるルールを使用しますが、1 つのグループは 1 つのグループにしかリンクできません。account_idaccount_id

もちろん、このクエリは機能しません。やりたいことを表現しようとしているだけです。これが理にかなっていることを願っています。

私は正確に何をどこに挿入したいかを知っているので、500account_id秒と 50group_id秒があることを知っているすべてのカウントを持っています。account_idまた、 1 から 500 と1 から 500 を意味する順番になっているgroup_idので、この場合、何らかの方法で挿入をループするのはかなり簡単だと思います。

私は自分自身をできるだけ明確にしたことを願っています。

あなたの答えと提案をありがとう!

4

3 に答える 3

1

このようなものが機能します。構文(ここINSERT ... SELECTの例を参照)を使用して、クエリから複数の行を挿入します。

ループするには、結果をこのクエリと相互結合します。これにより、連続番号を含む500行のテーブルが作成されます。

select LEVEL as group_id from dual connect by LEVEL <= 500

これが最終的な答えです。テストされていないため、修正と調整が必要になる場合がありますが、これが一般的なアプローチです。

insert into map (account_id, group_id)
  select account_id, group_id
    from account
    where company_id in (select company_id 
                         from company 
                         where company_name = 'string')
  cross join (select LEVEL as group_id
              from dual 
              connect by LEVEL <= 500)

追加-OPは、グループ1,000から1,500(1から500ではなく)を含むクエリがどのように機能するかを尋ねました...

CONNECT BY LEVEL常に1から開始する必要があるため、内部クエリで1から999までを外部WHERE句で除外する必要がありますCONNECT BY LEVEL <= 1500。これが例です。違いはすべて、相互結合されたクエリにあります。

insert into map (account_id, group_id)
  select account_id, group_id
    from account
    where company_id in (select company_id 
                         from company 
                         where company_name = 'string')
  cross join (
     select group_id from (
       select LEVEL as group_id
         from dual
         connect by LEVEL <= 1500)
     where group_id >= 1000)

現在、Oracleが手の届かないところにあるため、これは以前の回答のようにテストされていません。

また、このように1,500まで上げることは問題ありませんが、ある時点で速度が低下することに気付くでしょう。10,000、100,000、100万のいずれになるかはわかりませんが、遅かれ早かれ壁にぶつかる可能性があります。

于 2013-03-15T18:11:51.340 に答える
1

これにより、アカウント ID とグループ ID のすべての組み合わせが挿入されます。

INSERT INTO map(account_id, group_id)
SELECT a.id, g.id
FROM account a, group g
WHERE a.company_id IN ( select company_id 
                        from company 
                        where company_name = 'string');

編集:あなたが正しくコメントしたことを理解していれば、次のようなものが必要です:

INSERT INTO map(account_id, group_id)
SELECT a.id, g.id
FROM account a, group g
WHERE a.company_id IN ( SELECT company_id 
                        FROM company 
                        WHERE company_name = 'string')
AND 1000 <= a.id AND a.id <= 1500
AND g.id = a.id + 1000;

アカウント 1000 をグループ 2000 に、アカウント 1001 をグループ 2001 に、というように接続します。今すぐグループに参加する必要はありませんが、期待されるグループ ID を持つ行が存在することを確認します (存在しない場合はスキップします)。

于 2013-03-15T18:06:58.803 に答える
0

あなたの質問への答え:

INSERT INTO map(account_id, group_id)
SELECT a.id, g.id
  FROM account a
 INNER JOIN company c
    ON a.company_id = c.company_id
   AND c.company_name = 'string'
 CROSS JOIN group g

私のペットのおしっこ、SQL の制御をやめてください! を使用する必要はありませんIN

于 2013-03-15T19:07:44.367 に答える