0

別のテーブル(all_info)から1つのテーブル(some_data)に列を追加しようとしています。元々、id_aとid_bは十分な外部キーであり、これらを使用してテーブルall_infoから値を一意に識別し、テーブルsome_dataに取り込みます。ただし、どこかでsome_dataのid_bの一部が破損しました。したがって、id_aとid_bに完全一致がある場合、またはid_aとid_bに完全一致が存在しないが、その特定のid_aのエントリが1つしかない場合に、all_infoの値を引き続き使用する列をsome_dataに追加します。 all_info、それが私たちが望むものであると仮定します(そしてsome_dataの破損したid_bを置き換えます)

したがって、2つのテーブルが与えられると、

some_data        all_info
id_a | id_b      id_a | id_b | val
------------     --------------------
 1   | a          1   | a    | v_i
 2   | b          2   | c    | v_x
 3   | c          2   | b    | v_ii
 4   | d          3   | d    | v_iv
                  3   | e    | v_v
                  4   | f    | v_vi

入手したい:

id_a | id_b | val
------------------
 1   | a    | v_i
 2   | b    | v_ii
 3   | c    | NULL
 4   | f    | v_vi

これまで私は2つのアプローチを考えてきましたが、そのうちの1つは基本的に次のとおりです。

SELECT sd.*, ai.val
FROM some_data sd
LEFT OUTER JOIN all_info ai
ON sd.id_a = ai.id_a
  AND (sd.id_b = ai.id_b OR COUNT(*) = 1)

もちろん、それ自体は機能しません(また、不正なid_bを置き換えるという2番目の目標も達成しません)が、COUNT()関数を使用してさまざまなグループ化と選択を試みても、SQLが実行に十分適していると判断したものは見つかりませんでしたと。また、SETコマンドを列に入力してみようと思いましたが、それを機能させる方法が見つかりませんでした。

ちなみに、データを見ると、all_infoにはid_aとid_bの両方のsome_dataに一致する行がほとんど1行あるように見えます。また、id_aとid_bが一致する場合、id_bの複雑さを考えると、一致が正しいと見なすのが安全です。

4

2 に答える 2

1

選択は次のようになります。

SELECT sd.id_a, sd.id_b, 
       CASE WHEN ai.id_a IS NULL THEN ai2.val ELSE ai.val END as val

FROM   some_data sd

       LEFT JOIN all_info ai
       ON ad.id_a = ai.id_a AND ad_id_b = ai.id_b

       LEFT JOIN 
       (SELECT id_a, MIN(id_b) id_b, MIN(val) val
        FROM   all_info
        GROUP BY id_a
        HAVING COUNT(*) = 1
       ) ai2 ON sd.id_a = ai.id_a
于 2012-11-19T22:17:06.433 に答える
0

これを実行してデータを修正できます。

UPDATE some_data sd

       JOIN 
       (SELECT id_a, MIN(id_b) id_b
        FROM   all_info
        GROUP BY id_a
        HAVING COUNT(*) = 1
       ) ai ON sd.id_a = ai.id_a AND sd.id_b <> ai.id_b

SET    ad.id_b = ai.id_b
于 2012-11-19T22:10:42.873 に答える