You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现数据表中多字段关联行的全量查询?

问题描述

给定如下数据表:

| id       | user_id  | phone_number |    email        |
| -------- | -------- | ------------ | --------------- |
| 1        | 999      | 61412308310  |can@gmail.com    |
| 2        | 129      | 61477708777  |acdc@gmail.com   | 
| 3        | 213      | 61488908495  |adel99@gmail.com |
| 4        | 145      | 61477708777  |austr@gmail.com  | 
| 5        | 214      | 61421445777  |austr@gmail.com  |
| 6        | 214      | 61421445326  |jango@gmail.com  | 

需求:输入该数据集中user_id、phone_number、email任意一列的某个值,查询所有存在关联的行(包括间接关联)。

示例:当输入phone_number = 61477708777时,预期结果为:

| id       | user_id  | phone_number | email           |
| -------- | -------- | ------------ | --------------- |
| 2        | 129      | 61477708777  |acdc@gmail.com   | 
| 4        | 145      | 61477708777  |austr@gmail.com  | 
| 5        | 214      | 61421445777  |austr@gmail.com  |
| 6        | 214      | 61421445326  |jango@gmail.com  | 

关联逻辑:

  • id=2和id=4直接匹配查询条件;
  • id=5与id=4共享相同email;
  • id=6与id=5共享相同user_id;
    以上所有关联行都需要被检索出来。

现有函数仅能匹配直接符合条件的行,无法处理间接关联:

def search_data(field, value, data):
    data_dict = {}
    for row in data:
        key = row[field]
        if key not in data_dict:
            data_dict[key] = []
        data_dict[key].append(row)
    return data_dict.get(value, [])

解决方案

这个问题本质是图的连通分量查找:把每一行看作一个节点,只要两行共享user_id、phone_number或email中的任意一个值,就认为它们之间有连接。我们需要找出与初始节点直接或间接连通的所有节点。

实现步骤

  1. 为三个字段分别建立索引:记录每个字段值对应的所有行,方便快速查找关联行。
  2. 使用广度优先搜索(BFS)或深度优先搜索(DFS),从初始匹配的行出发,不断扩展所有关联行,直到没有新的行加入。
  3. 去重:用行的id作为唯一标识,避免重复处理同一行。

代码实现

def find_related_rows(field, value, data):
    # 建立三个字段的索引:字段值 -> 对应的行列表
    indexes = {
        'user_id': {},
        'phone_number': {},
        'email': {}
    }
    for row in data:
        for idx_field in indexes:
            key = row[idx_field]
            if key not in indexes[idx_field]:
                indexes[idx_field][key] = []
            indexes[idx_field][key].append(row)
    
    # 获取初始匹配的行
    initial_rows = indexes[field].get(value, [])
    if not initial_rows:
        return []
    
    # BFS遍历所有关联行
    visited_ids = set()
    queue = []
    # 初始化队列和已访问集合
    for row in initial_rows:
        if row['id'] not in visited_ids:
            visited_ids.add(row['id'])
            queue.append(row)
    
    while queue:
        current_row = queue.pop(0)  # 改用pop()即为DFS遍历
        # 遍历当前行的三个字段,查找关联行
        for idx_field in indexes:
            key = current_row[idx_field]
            for related_row in indexes[idx_field].get(key, []):
                if related_row['id'] not in visited_ids:
                    visited_ids.add(related_row['id'])
                    queue.append(related_row)
    
    # 返回按id排序的结果
    return sorted([row for row in data if row['id'] in visited_ids], key=lambda x: x['id'])

测试示例

假设数据以字典列表形式存储:

data = [
    {'id': 1, 'user_id': 999, 'phone_number': '61412308310', 'email': 'can@gmail.com'},
    {'id': 2, 'user_id': 129, 'phone_number': '61477708777', 'email': 'acdc@gmail.com'},
    {'id': 3, 'user_id': 213, 'phone_number': '61488908495', 'email': 'adel99@gmail.com'},
    {'id': 4, 'user_id': 145, 'phone_number': '61477708777', 'email': 'austr@gmail.com'},
    {'id': 5, 'user_id': 214, 'phone_number': '61421445777', 'email': 'austr@gmail.com'},
    {'id': 6, 'user_id': 214, 'phone_number': '61421445326', 'email': 'jango@gmail.com'},
]

# 查询phone_number=61477708777的关联行
result = find_related_rows('phone_number', '61477708777', data)
# 打印结果表格
print("| id       | user_id  | phone_number | email           |")
print("| -------- | -------- | ------------ | --------------- |")
for row in result:
    print(f"| {row['id']:<8} | {row['user_id']:<8} | {row['phone_number']:<12} | {row['email']:<15} |")

运行后会输出符合预期的结果。

说明

  • 索引的建立避免了每次查找都遍历整个数据集,提升了查询效率。
  • BFS/DFS确保能覆盖所有直接和间接关联的行,不会遗漏。
  • 用id作为唯一标识去重,避免重复处理同一行。

内容的提问来源于stack exchange,提问作者wdad asd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 19:20:25