2009-12-01 19 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

相關問題