使用两个密钥检索尽可能多的数据,其中一个密钥已损坏

时间:2012-11-19 21:49:18

标签: mysql sql

我正在尝试从另一个表(all_data)向一个表(some_data)添加一个列;最初,id_a和id_b将是一个足够的外键,我将使用它们来唯一地标识表all_info中的值,以带来表some_data。但是,某些地方 some_data中id_b的某些已损坏。因此,我想在some_data中添加一个列,当id_a和id_b存在完全匹配时仍然使用all_info中的值,或者,如果id_a和id_b上不存在完全匹配,但是对于该特定id_a只有一个条目all_info,我们假设这是我们想要的(并替换some_data中损坏的id_b)

所以,给定两个表,

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

到目前为止,我已经想到了两种方法,其中一种方法是基本的:

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的第二个目标),但尝试用COUNT()函数进行各种分组和选择我找不到SQL发现的任何东西足以运行。我还想尝试使用SET命令填充列,但又找不到使其工作的方法。

作为旁注,看看数据似乎all_info在AT MOST上有一行与id_a和id_b上的some_data匹配。此外,当id_a和id_b匹配时,考虑到id_b的复杂性,可以安全地假设匹配是正确的。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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