无论顺序如何,计算多列值的唯一组合?

Counting unique combinations of values across multiple columns regardless of order?

我有一个 table 看起来有点像这样:

Customer_ID | Offer_1 | Offer_2 | Offer_3
------------|---------|---------|--------
111         | A01     | 001     | B01
222         | A01     | B01     | 001
333         | A02     | 001     | B01

我想编写一个查询来计算 table 中有多少独特的优惠组合,而不管优惠出现的顺序如何。

所以在上面的例子中有两个独特的组合:客户 111 和 222 都有相同的三个报价,所以他们算作一个独特的组合,然后客户 333 是唯一拥有他们拥有的三个订单的客户.所以查询的期望输出是 2.

对于一些额外的上下文:

我可以将所有报价列连接在一起,然后 运行 计算结果的不同语句,但这不考虑具有相同唯一报价组合但订购方式不同的客户(例如上例中的客户 111 和 222)。

请问有人知道如何解决这个问题吗?

一种方法是将优惠 union all 放入一列,然后使用 select distinct listagg... 获取优惠组合。试试这个:

with u as
(select Customer_ID, Offer_1 as Offer from table_name union all
 select Customer_ID, Offer_2 as Offer from table_name union all
 select Customer_ID, Offer_3 as Offer from table_name)
select distinct listagg(Offer, ',') within group(order by Offer) from u
group by Customer_ID

Fiddle

假设字符 / 没有出现在任何报价名称中,您可以这样做:

select count(distinct offer_combo) as distinct_offers
from (
  select listagg(offer, '/') within group (order by offer) as offer_combo
  from (
    select customer_id, offer_1 as offer from t
    union all select customer_id, offer_2 from t
    union all select customer_id, offer_3 from t
  ) x
  group by customer_id
) y

结果:

DISTINCT_OFFERS
---------------
2

参见 db<>fiddle 中的 运行 示例。

没有UNION ALL的解决方案。它应该有更好的性能。

/*
WITH MYTAB (Customer_ID, Offer_1, Offer_2, Offer_3) AS
(
VALUES
  (111, 'A01', '001', 'B01')
, (222, 'A01', 'B01', '001')
, (333, 'A02', '001', 'B01')
)
*/
SELECT COUNT (DISTINCT LIST)
FROM
(
SELECT LISTAGG (V.Offer, '|') WITHIN GROUP (ORDER BY V.Offer) LIST 
FROM MYTAB T
CROSS JOIN TABLE (VALUES T.Offer_1, T.Offer_2, T.Offer_3) V (Offer)
GROUP BY T.CUSTOMER_ID
)