Python中的Sort-Merge-Join算法

时间:2016-02-07 08:03:01

标签: python database algorithm

我的代码:

 def merge_join(self, outer, outer_join_index, inner, inner_join_index):
    a=list(inner)
    b=list(outer)
    if not a or not b:
        return
    inner_copy = sorted(a,key=lambda tup: tup[inner_join_index])
    outer_copy = sorted(b,key=lambda tup: tup[outer_join_index])
    inner_counter=0
    outer_counter=0
    while inner_counter < len(inner_copy) and outer_counter < len(outer_copy):
        if outer_copy[outer_counter][outer_join_index]==inner_copy[inner_counter][inner_join_index]:
            yield outer_copy[outer_counter]+inner_copy[inner_counter]
            outer_counter+=1
        elif outer_copy[outer_counter][outer_join_index]<inner_copy[inner_counter][inner_join_index]:
            outer_counter+=1
        else:
            inner_counter+=1

外部和内部是发电机。

我为算法运行了一个给定的测试,但它返回了一个127个元素的生成器,而不是预期的214个。有人可以帮我检查我的代码中的bug可能在哪里吗?谢谢!!

1 个答案:

答案 0 :(得分:0)

如果您想为每个outer行选择正确的inner行(inner中没有重复行,如果没有匹配则跳过行,那么如果匹配,则为应该像你一样增加inner_counter,而不是outer_counter

原因是否则如果多个内部行具有相同的值,则只输出其中的第一行。

如果您想要进行完全连接(从innerouter为连接列的给定值生成行的所有笛卡尔积),则必须使用某些内容明确编码像

while inner_counter < len(inner_copy) and outer_counter < len(outer_copy):
    key = min(inner_copy[inner_index][inner_join_index],
              outer_copy[outer_index][outer_join_index])
    inner_group = []
    while inner_index < len(inner) and key == inner_copy[inner_index][inner_join_index]:
        inner_group.append(inner_copy[inner_index])
        inner_index += 1
    outer_group = []
    while outer_index < len(outer) and key == outer_copy[outer_index][outer_join_index]:
        outer_group.append(outer_copy[outer_index])
        outer_index += 1
    # Here you can handle left or right join by replacing an
    # empty group with a group of one empty row (None,)*len(row)
    for i in inner_group:
        for o in outer_group:
            yield i + o