如何使用SQLAlchemy ORM获取数据库表多列的独立去重值?
问题描述
我创建了包含以下表的数据库:
Employee(id, name, deptid, salary) Department(id, name)
表中数据如下:
Employee表
| id | name | deptid | salary |
|---|---|---|---|
| 1 | Alex | 1 | 600000 |
| 2 | Larry | 1 | 700000 |
| 3 | Jesse | 3 | 400000 |
| 4 | Alex | 2 | 500000 |
| 5 | Marcus | 3 | 400000 |
Department表
| id | name |
|---|---|
| 1 | Engineering |
| 2 | Finance |
| 3 | Sales |
我想要获取Employee表中name和deptid列各自的独立去重值,期望输出如下:
name ------ Alex Larry Jesse Marcus deptid ------- 1 3 2
我尝试用ORM查询:
session.query(Employee.name, Employee.deptid).distinct().all()
但返回的是两列组合后的去重结果:
[('Alex',1,), ('Larry',1), ('Jesse', 3),('Alex',2),('Marcus',3)]
这不是我要的,我需要在单个查询中拿到不同列各自独立的去重值。
解决方案
要实现单个查询获取多列各自独立的去重值,你可以通过子查询+UNION ALL的方式构造逻辑,再用ORM或原生SQL执行:
方法1:SQLAlchemy ORM实现
from sqlalchemy import select, union_all, String # 分别查询name和deptid的去重值,新增标识列区分数据类型 name_subq = select(Employee.name.label('value'), select('name').label('type')).distinct() deptid_subq = select(Employee.deptid.cast(String).label('value'), select('deptid').label('type')).distinct() # 合并两个子查询 combined_query = union_all(name_subq, deptid_subq) # 执行查询并整理结果 results = session.execute(combined_query).fetchall() name_list = [row.value for row in results if row.type == 'name'] deptid_list = [row.value for row in results if row.type == 'deptid'] # 按期望格式输出 print("name") print("------") for name in name_list: print(name) print("\ndeptid") print("-------") for deptid in deptid_list: print(deptid)
方法2:原生SQL实现
如果更倾向直接写SQL,可构造如下查询:
sql = """ SELECT name AS value, 'name' AS type FROM Employee GROUP BY name UNION ALL SELECT CAST(deptid AS VARCHAR) AS value, 'deptid' AS type FROM Employee GROUP BY deptid """ results = session.execute(sql).fetchall() # 后续整理输出逻辑和方法1一致
关键说明
- 由于
name是字符串类型,deptid是数值类型,需要将deptid转为字符串,保证UNION ALL时列类型兼容。 - 通过新增的
type标记列,可轻松拆分出两列各自的去重值。
内容的提问来源于stack exchange,提问作者Glen Veigas
相关产品推荐
相关产品推荐

