基于DB2 SQL的客户偏好产品分析及SQL语句优化需求
DB2 SQL实现客户偏好产品合并排名
针对你的需求,我们可以通过密集排名+分组聚合+条件判断的组合来实现同CNT值产品合并到同一偏好列,同时处理全CNT为0的场景,具体SQL如下:
WITH ranked_data AS ( -- 1. 给每个客户的产品按CNT降序计算密集排名,相同CNT获相同排名 SELECT ID, SERVICE_TYPE, CNT, DENSE_RANK() OVER(PARTITION BY ID ORDER BY CNT DESC) AS rnk FROM your_table_name -- 替换成你的实际表名 ), rank_agg AS ( -- 2. 按客户+排名分组,合并同排名的服务类型 SELECT ID, rnk, LISTAGG(SERVICE_TYPE, ', ') WITHIN GROUP(ORDER BY SERVICE_TYPE) AS service_list FROM ranked_data GROUP BY ID, rnk ), pivoted_data AS ( -- 3. 将排名转成第一/第二/第三偏好列 SELECT ID, MAX(CASE WHEN rnk = 1 THEN service_list END) AS first_preference, MAX(CASE WHEN rnk = 2 THEN service_list END) AS second_preference, MAX(CASE WHEN rnk = 3 THEN service_list END) AS third_preference FROM rank_agg GROUP BY ID ), non_user_check AS ( -- 4. 判断客户是否全CNT为0,是则替换所有偏好列为'Non user' SELECT p.ID, CASE WHEN MAX(t.CNT) = 0 THEN 'Non user' ELSE p.first_preference END AS first_preference, CASE WHEN MAX(t.CNT) = 0 THEN 'Non user' ELSE p.second_preference END AS second_preference, CASE WHEN MAX(t.CNT) = 0 THEN 'Non user' ELSE p.third_preference END AS third_preference FROM pivoted_data p LEFT JOIN your_table_name t ON p.ID = t.ID GROUP BY p.ID, p.first_preference, p.second_preference, p.third_preference ) SELECT * FROM non_user_check;
关键逻辑说明:
- 密集排名(DENSE_RANK):和ROW_NUMBER不同,它会给相同CNT的产品分配相同排名,这是实现同CNT合并的核心
- LISTAGG聚合:将同排名的SERVICE_TYPE拼接成字符串,满足合并需求,你可以修改分隔符(比如
'; ')适配你的格式要求 - 条件聚合转列:通过CASE WHEN+MAX把排名1/2/3映射到对应的偏好列,没有对应排名的列会返回NULL
- 全0判断:通过关联原表取MAX(CNT),如果等于0说明该客户所有产品CNT都是0,统一替换为'Non user'
注意事项:
- 如果需要保留CNT=0的产品参与排名(比如部分产品CNT=0、部分非0的场景),该逻辑会自动将所有CNT=0的产品合并到同一排名列中
- 若客户的产品排名超过3,只会保留前3名的结果,后续排名会被忽略
内容的提问来源于stack exchange,提问作者Mwai.John
相关产品推荐
相关产品推荐

