我的数据如下所示:
身份证 | 服务类型 | 碳纳米管 |
---|---|---|
12345678 | 萨科斯 | 0 |
12345678 | 零售_中小企业 | 0 |
12345678 | TRANS_LOGISTIC | 0 |
12345678 | 医疗保健 | 0 |
12345678 | 能源 | 7 |
12345678 | 非政府组织 | 0 |
12345678 | 技术服务 | 0 |
12345678 | 商业服务 | 0 |
12345678 | 宗教 | 0 |
12345678 | 保险 | 0 |
12345678 | 教育 | 0 |
12345678 | 小额信贷 | 0 |
12345678 | LOAN_REP_COUNT | 2 |
12345678 | 水单 | 0 |
12345678 | 付费电视 | 0 |
12345678 | MERCHPAY_OP | 1 |
12345678 | MERCHPAY_AM | 0 |
12345678 | 投注 | 0 |
12345678 | AMTk_BUNDLE | 0 |
12345678 | AMTK_AIRTIME_RECH | 1 |
12345678 | 电费账单 | 0 |
12345678 | W2B | 0 |
12345678 | P2P_UNREG | 0 |
12345678 | P2P_OPTK | 1 |
12345678 | P2P_AMTK | 1 |
12345678 | 提现 | 0 |
12345678 | IMT | 0 |
12345678 | 农业 | 0 |
12345678 | 航空 | 0 |
12345678 | 运动 | 0 |
12345678 | 建筑 | 0 |
12345678 | 餐饮 | 0 |
12345678 | 聚合器 | 0 |
12345678 | 媒体 | 0 |
12345678 | 快消品 | 0 |
目标是找到客户的首选产品,方式是:我了解客户 A 更喜欢产品 X,下一个最佳报价是产品 Y,第三个最佳报价是产品 Z (s).
对于具有相同数量的产品,它们应出现在一列中。例如本例。
它应该看起来像这样:
身份证 | FIRST_PREF_LEG | SECOND_PREF_LEG | 第三_PREF_LEG |
---|---|---|---|
12345678 | 能源 | LOAN_REP_COUNT | AMTK_AIRTIME_RECH、P2P_OPTK、P2P_AMTK |
另一个例子是,如果客户有两种 CNT 相等的产品(比如 2),那么这应该是客户的第一个 Pref Leg,并且所有产品都应该在那里
如果客户只有 0 CNT,我们应该在所有 Pref Leg 中将该客户标记为“非用户”。
我试过这个:
WITH RankedServices AS
(
SELECT
ID,
COALESCE(SERVICE_TYPE, 'non-user') AS SERVICE_TYPE,
RANK() OVER (PARTITION BY ID ORDER BY COALESCE(CNT, 0) DESC) AS rnk
FROM
Table_name_tableA
WHERE
COALESCE(CNT, 0) > 0 -- Exclude products with count 0
)
SELECT
ID,
MAX(CASE WHEN rnk = 1 THEN SERVICE_TYPE END) AS First_Pref_Leg,
MAX(CASE WHEN rnk = 2 THEN SERVICE_TYPE END) AS Second_Pref_Leg,
MAX(CASE WHEN rnk = 3 THEN SERVICE_TYPE END) AS Third_Pref_Leg
FROM
RankedServices
GROUP BY
ID;
这是结果:
身份证 | FIRST_PREF_LEG | SECOND_PREF_LEG | 第三_PREF_LEG |
---|---|---|---|
12345678 | 能源 | LOAN_REP_COUNT | P2P_OP |
在我期待的时候:
身份证 | FIRST_PREF_LEG | SECOND_PREF_LEG | 第三_PREF_LEG |
---|---|---|---|
12345678 | 能源 | LOAN_REP_COUNT | AMTK_AIRTIME_RECH、P2P_OPTK、P2P_AMTK |
你可以这样做:
select id,
listagg(case when dr = 1 then service_type end, ',') as first,
listagg(case when dr = 2 then service_type end, ',') as second,
listagg(case when dr = 3 then service_type end, ',') as third
from (
select t.*, dense_rank() over(partition by id order by cnt desc) as dr
from t where cnt > 0
) x
group by id
结果:
ID FIRST SECOND THIRD
-------- ------ -------------- -------------------------
12345678 ENERGY LOAN_REP_COUNT MERCHPAY_OP,AMTK_AIRTIME_RECH,P2P_OPTK,P2P_AMTK
请参阅 db<>fiddle 处的运行示例。