2009-12-01 69 views
1
table a (t_a): 
id name last first email   state country 
0 sklass klass steve [email protected] in  uk 
1 jabid abid john [email protected] ny  us 
2 jcolle colle john [email protected] wi  us 


table b (t_b): 
id sn  given nick email   l c 
0 steven klass steve [email protected] in uk 
1 john abid -  [email protected] ny us 
2 johnny colle john [email protected] wi us 
3 john abid -  [email protected] ny us 

上面列出的是一个(略)列和行mySQL表。看看这两个表格,通过严格查看值(id没有看到)并比较匹配的值的数量,您将会得到这些值匹配,这变得非常清楚。加入两个不同的mySQL表的最好方法 - 从python规划django

t_a  t_b 
0  0 
1  3 
2  2 
-  1 

我最终希望做的是在Django中做到这一点 - 我不确定是否重要。在过去,我使用纯python完成了这个工作,在这个工具中,我销毁了旧数据并创建了三个新表。我想从我的实现中转移出来(下面列出),因为我看到的问题是时间会改变事物和人们的来去。在过去,我刚刚重新生成了数据 - 但现在我想跟踪人们何时离开,而不是简单地更换(删除)数据。我相信通过执行SQL更新会更加优雅并保留历史记录。

我想知道如何从mySQL(SQL函数或一个新表的构造)直接得到这个合并的答案,以下列方式合并数据。我想用纯SQL做这件事(我相信我可以在Django中做到这一点)。所以我要寻找符合以下条件的解决方案:

  1. 有一个min_match定义了两排,其中必须对准被认为是有效之间的匹配的最小数量。
  2. 虽然表格可能有不同的长度,但它是1对1映射。换句话说,许多对一个可能不会发生(还)

现在我的背景是python和对我来说最简单的方法做到这一直是做一个循环在两个表中较短的,然后在另一张桌子上查看匹配数量的for循环。在代码中,这看起来像这样。

t_a = [ ["sklass", "klass", "steve", "[email protected]", "in", "uk", ], 
     ["jabid", "abid", "john", "[email protected]", "ny", "us", ], 
     ["jcolle", "colle", "john", "[email protected]", "wi", "us", ], ] 

t_b = [ ["steven", "klass", "steve", "[email protected]", "in", "uk",], 
     ["john", "abid", "[email protected]", "ny", "us",], 
     ["johnny", "colle", "john", "[email protected]", "wi", "us",], 
     ["john", "abid", "[email protected]", "ny", "us",], ] 

min_match = 3 

for person_a in t_a: 
    match = 0 
    match_pct = 0.0 
    match_a_index = t_a.index(person_a) 
    for person_b in t_b: 
     new_match_count = len(list(set(person_a) & set(person_b))) 
     if new_match_count > match: 
      match = new_match_count 
      match_b_index = t_b.index(person_b) 
      match_pct = "%.2f" % (float(new_match_count)/\ 
       float(len(set(person_a + person_b))) * 100) 
    if match >= min_match: 
     print match_a_index, match_b_index #, match_pct, match 

该评论提出了问题,为什么你不加入电子邮件地址。我不一定知道列中的值会匹配。 I am确定来自t_a中的给定行的值将与t_b中的行的值匹配。我希望t_a到t_b中给定行的最高(最可能)匹配,并且只在匹配数量高于min_match时匹配。

+0

你能澄清你的预期产出是什么吗?你不能只是完全加入两个表格之间的电子邮件地址吗? – 2009-12-01 16:04:35

回答

1

您可以直接通过存储过程执行的游标在MySQL中执行此操作。

DELIMITER $$ 
CREATE PROCEDURE `proc_name`() 
BEGIN 
    DECLARE done INT DEFAULT 0; 
    DECLARE a_id BIGINT UNSIGNED; 
    DECLARE b_id BIGINT UNSIGNED; 
    DECLARE x_count INT; 

    -- something like the following 
    DECLARE cur1 CURSOR FOR SELECT t_a.id, t_b.id FROM t_a, t_b WHERE t_a.email = t_b.email; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 

    SELECT COUNT(*) INTO x_count FROM t_a, t_b WHERE t_a.email = t_b.email; 

    IF(x_count > <some_min_value>) THEN 

    OPEN cur1; 

    REPEAT 
     FETCH cur1 INTO a_id, b_id; 
     IF NOT done THEN 

     -- do something here like update rows, remove rows, etc. 
     -- a_id and b_id hold the two id values for the two tables which 
     -- I assume to be primary keys 

     END IF; 
    UNTIL done END REPEAT; 

    CLOSE cur1; 

    END IF; 
END 
$$ 
+0

嘿特雷西, 太棒了!因此,这假定您有值的列匹配。但我不一定知道哪些列将匹配(例如,一列中的昵称可能与另一个表中的一列或多列匹配。)所以我认为你的近似,但有没有一种方法来迭代计数匹配值? 再次感谢! – rh0dium 2009-12-01 16:44:53