SQL合并两个没有唯一键的大数据表

时间:2012-12-06 11:44:52

标签: sql sql-server-2012 bigdata

我有以下需要合并的表:

表1:

  

main_key | sec_key | old_number | var1 | VAR2

 1      |  A    |    5     | AA | 11
 1      |  B    |    8     | BB | 22

表2:

  

main_key | new_number | var1 | VAR2

 1      |   2       | DD | 44
 1      |   3       | EE | 55
 1      |   7       | FF | 66

我无法修改表格(没有插入因此我不能使用'merge',只能使用UNION)。

两个表都包含大量数据,我需要最有效的方法来合并它们。

  • 合并应该根据main_key,并且对于每个table1.sec_key,
  • 如果table2.new_number< table1.old_number,然后将table1.var1,table1.var2的值更新为相应的值:table2.var1和table2.var2。

此外,原始table1值应该与old_number一行。

示例:

  • 对于第一个table1.sec_key:其old_number为5。
  • table2.new_number'2'小于5,table2.new_number'3'小于5但table2.new_number'7'大于5
  • 所以输出将包含old_numbers以及new_number = 2和new_number = 3的行:

(对于其他sec_keys和其他main_keys中的所有其他sec_keys也是如此。

示例的预期output_table:

main_key | sec_key | number | var1 | var2
    1    |    A    |    5   |  AA  |  11
    1    |    A    |    2   |  DD  |  44     
    1    |    A    |    3   |  EE  |  55
    1    |    B    |    8   |  BB  |  22  
    1    |    B    |    2   |  DD  |  44     
    1    |    B    |    3   |  EE  |  55
    1    |    B    |    7   |  FF  |  66

我想过要么使用UNION,要么加入,但不知道怎么做,并为每个sec_key保留table1的原始行。

我的问题是main_key不是唯一键。 我也考虑过使用CTE但不确定它在这里有用。

1 个答案:

答案 0 :(得分:1)

在我看来,您需要来自table1的数据的UNION以及table1table2的专门联接:

SELECT main_key, sec_key, old_number AS number, var1, var2
  FROM table1
UNION
SELECT t1.main_key, t1.sec_key, t2.new_number AS number, t2.var1, t2.var2
  FROM table1 AS t1
  JOIN table2 AS t2 ON t2.main_key = t1.main_key AND t2.new_number < t1.old_number

在您的测试数据上,它会产生您想要的答案(由ORDER BY main_key, sec_key, number控制的排序):

1   A   2   DD   44
1   A   3   EE   55
1   A   5   AA   11
1   B   2   DD   44
1   B   3   EE   55
1   B   7   FF   66
1   B   8   BB   22

如果你真的希望原始行出现在合并的行之前,你需要做更多的工作:

SELECT u.main_key, u.sec_key, u.number, u.var1, u.var2
  FROM (SELECT 0 AS pseudo_order, main_key, sec_key, old_number AS number, var1, var2
          FROM table1
        UNION
        SELECT 1 AS pseudo_order, t1.main_key, t1.sec_key, t2.new_number AS number,
               t2.var1, t2.var2
          FROM table1 AS t1
          JOIN table2 AS t2 ON t2.main_key = t1.main_key AND t2.new_number < t1.old_number
       ) AS u
 ORDER BY u.pseudo_order, u.main_key, u.sec_key, u.number;

输出:

1   A   5   AA   11
1   A   2   DD   44
1   A   3   EE   55
1   B   8   BB   22
1   B   2   DD   44
1   B   3   EE   55
1   B   7   FF   66