PostgreSQL中如何按分组返回每组一行数据?
如何为每个customerid返回任意一个addressid?
我明白你的需求——你想对每个customerid只返回任意对应的一个addressid,之前试了DISTINCT没用,直接GROUP BY customerid又会丢失addressid字段,对吧?下面给你几种实用的解决方法,覆盖不同主流数据库场景:
方案1:使用窗口函数(通用主流数据库支持)
这个方法适用于MySQL 8.0+、PostgreSQL、SQL Server等支持窗口函数的数据库,用ROW_NUMBER()给每个customerid分组内的行编号,然后取编号为1的行即可。因为要的是任意一个,排序规则可以随便指定(甚至不指定):
SELECT customerid, addressid FROM ( SELECT customerid, addressid, -- 按customerid分组,不指定排序规则,数据库会随机/按存储顺序取第一个 ROW_NUMBER() OVER (PARTITION BY customerid ORDER BY (SELECT NULL)) AS rn FROM addresses -- 这里替换成你的WHERE条件 ) AS sub_query WHERE rn = 1;
方案2:数据库专属聚合函数/简化写法
MySQL 专属
MySQL提供了ANY_VALUE()函数,专门用来在GROUP BY时返回分组内的任意值,完美匹配你的需求:
SELECT customerid, ANY_VALUE(addressid) AS addressid FROM addresses -- 替换成你的WHERE条件 GROUP BY customerid;
PostgreSQL 专属
你可以用MIN()/MAX()(虽然是取最小/最大值,但也满足“任意一个”的要求),或者用数组聚合后取第一个元素:
-- 用MIN/MAX的简化写法 SELECT customerid, MIN(addressid) AS addressid FROM addresses -- 替换成你的WHERE条件 GROUP BY customerid; -- 用数组取任意第一个的写法 SELECT customerid, (array_agg(addressid))[1] AS addressid FROM addresses -- 替换成你的WHERE条件 GROUP BY customerid;
SQL Server 专属
可以用FIRST_VALUE()窗口函数配合DISTINCT,或者同样用MIN()/MAX():
SELECT DISTINCT customerid, FIRST_VALUE(addressid) OVER (PARTITION BY customerid ORDER BY (SELECT NULL)) AS addressid FROM addresses -- 替换成你的WHERE条件
为什么DISTINCT对你的场景没用?
你之前用的SELECT DISTINCT customerid, addressid是对customerid + addressid的组合行去重,而你的数据里每个客户对应多个不同的addressid,每一行都是唯一的,所以这个语句不会过滤掉任何行,自然达不到你想要的效果。
内容的提问来源于stack exchange,提问作者avi
相关产品推荐
相关产品推荐

