SQL中按Customer分组并拼接其已开通产品的实现方法咨询
实现方案
你当前编写的查询语法不合法:当GROUP BY维度为CustomerKey时,不能直接SELECT未做聚合处理的ProductType字段,以下是对应两个需求的实现方法:
1. 生成客户去重产品拼接字段
不同SQL引擎的对应聚合函数如下:
- MySQL:使用
GROUP_CONCAT函数
SELECT CustomerKey, GROUP_CONCAT(DISTINCT ProductType ORDER BY ProductType SEPARATOR '/') AS Products FROM share GROUP BY CustomerKey;
- PostgreSQL / SQL Server 2017及以上:使用
STRING_AGG函数
SELECT CustomerKey, STRING_AGG(DISTINCT ProductType, '/') WITHIN GROUP (ORDER BY ProductType) AS Products FROM share GROUP BY CustomerKey;
- Hive / Spark SQL:使用
concat_ws搭配collect_set实现去重拼接
SELECT CustomerKey, concat_ws('/', sort_array(collect_set(ProductType))) AS Products FROM share GROUP BY CustomerKey;
上述逻辑中已默认对同客户重复的产品做去重处理,符合你示例中多条Savings仅保留一次的需求。
2. 生成产品组合持有标识列
你示例中的标识列是判断客户是否同时持有对应组合的所有产品,使用条件聚合即可实现,语法兼容所有主流SQL引擎,和拼接字段的逻辑结合后的完整查询如下(以MySQL为例,其他引擎替换拼接函数即可):
SELECT CustomerKey, GROUP_CONCAT(DISTINCT ProductType ORDER BY ProductType SEPARATOR '/') AS Products, -- 同时持有Checking和Savings返回1,否则返回0 MAX(CASE WHEN ProductType = 'Checking' THEN 1 ELSE 0 END) * MAX(CASE WHEN ProductType = 'Savings' THEN 1 ELSE 0 END) AS `Checking/Savings`, -- 同时持有Savings和IRA返回1,否则返回0 MAX(CASE WHEN ProductType = 'Savings' THEN 1 ELSE 0 END) * MAX(CASE WHEN ProductType = 'IRA' THEN 1 ELSE 0 END) AS `Savings/IRA` FROM share GROUP BY CustomerKey;
如果你需要的是单个产品的持有标识,不需要做乘法运算,直接保留单个
MAX(CASE WHEN ProductType = '对应产品名' THEN 1 ELSE 0 END)即可。
内容的提问来源于stack exchange,提问作者user14316330
相关产品推荐
相关产品推荐

