PostgreSQL如何按相同名字分组返回符合姓氏模糊查询的行?
实现按名字分组返回全部匹配行的PostgreSQL查询
你的需求完全可以实现,原查询SELECT * FROM users WHERE l_name LIKE "Smi%" GROUP BY f_name报错的原因是:PostgreSQL的GROUP BY语法要求,SELECT子句中的列要么出现在GROUP BY列表里,要么被聚合函数包裹。你直接SELECT *但只按f_name分组,其他列既不在分组字段中也没有聚合,所以数据库无法确定如何返回这些列的值。
下面是几种符合你需求的实现方式:
1. 将每组行打包为集合字段返回
如果需要把同一f_name的所有行打包成单个数组或JSON对象,可以用聚合函数array_agg或json_agg:
用JSON格式聚合整行
SELECT f_name, json_agg(users) AS group_rows FROM users WHERE l_name LIKE 'Smi%' GROUP BY f_name;
返回结果中,group_rows字段会是一个JSON数组,包含该名字下所有匹配姓氏的完整行数据。
用数组格式聚合整行
SELECT f_name, array_agg(row_to_json(users)) AS group_rows FROM users WHERE l_name LIKE 'Smi%' GROUP BY f_name;
和JSON聚合类似,只是返回的是PostgreSQL数组类型,内部是JSON对象。
2. 按名字分组排序展示(无需聚合)
如果只是需要让相同名字的行连续展示,不需要打包成单个字段,直接用ORDER BY即可:
SELECT * FROM users WHERE l_name LIKE 'Smi%' ORDER BY f_name;
这样查询结果会按f_name排序,相同名字的行会集中在一起,你可以直观看到每组的全部行。
3. 用窗口函数标记分组
如果需要保留每行的完整数据,同时明确区分不同分组及组内行的顺序,可以用窗口函数:
SELECT *, row_number() OVER (PARTITION BY f_name ORDER BY l_name) AS group_row_num FROM users WHERE l_name LIKE 'Smi%';
group_row_num字段会标记当前行在其f_name组内的序号,方便你识别分组和组内行的顺序。
内容的提问来源于stack exchange,提问作者LePerMu
相关产品推荐
相关产品推荐

