Sql 当零件号不是每行一个,而是有分隔符“时,查找不同的客户id”/&引用;

Sql 当零件号不是每行一个,而是有分隔符“时,查找不同的客户id”/&引用;,sql,teradata,Sql,Teradata,有一个与此类似的数据集 Customer_id PART_N PART_C TXN_ID B123 268888 7902/7900 159 B123 12839 82900/8900 1278 B869 12839 8203/890025/7902 17890 B290 268888 62820/12839 179018 不确定如何组合零件N和零件C,并为每个零件查找

有一个与此类似的数据集

Customer_id PART_N  PART_C           TXN_ID
B123        268888  7902/7900        159
B123        12839   82900/8900       1278
B869        12839   8203/890025/7902 17890
B290        268888  62820/12839      179018
不确定如何组合零件N和零件C,并为每个零件查找计数(不同的客户id)。同一零件可能位于零件N或零件C中,如零件号12839

我对使用teradata获得下表感兴趣

Part    COUNT(Distinct Customer id)
268888  2
12839   3
7902    2
7900    1
82900   1
8900    1
8203    1
890025  1
62820   1

如果只是零件号,那么它将是直接的,因为每行只有一个零件号。不确定我如何组合每个零件号并找到每个零件有多少不同的客户id。如果有帮助的话,我可以将所有不同的零件号列表放在一个表中,比如表2。

我不能尝试此代码,所以请将其视为伪代码和想法草图

SELECT numbers, COUNT(numbers)
FROM
    (SELECT 
        REGEXP_SPLIT_TO_TABLE(             -- B
            CONCAT(PART_N, '/', PART_C),   -- A
            '/'
        ) as numbers
    FROM table) s
GROUP BY numbers                           -- C
A:将两个列连接成一个字符串,并用分隔符“/”分隔

B:按分隔符拆分字符串

C:将字符串部分分组并计数

这太难看了

首先,让我们使用
strtok\u split\u to\u table
将这些分隔字符串拆分

create volatile table vt_split as (
select
txn_id,
token as part
from table
    (strtok_split_to_table(your_table.txn_id,your_table.part_c,'/')
    returns (txn_id integer,tokennum integer,token varchar(10))) t
)
with data
primary index (txn_id)
on commit preserve rows;
这将给你所有这些分开,与适当的txn_id。 然后我们可以将其与part\n值合并

create volatile table vt_merged as  (
select * from vt_split
UNION ALL
select
txn_id,
cast(part_n as varchar(10)) as part
from
vt_foo)
with data
primary index (txn_id)
on commit preserve rows;
最后,我们可以将其连接回原始表,以按部分获得客户计数

select
    vt_merged.part,
    count (distinct yourtable.customer_id)
from
vt_merged
inner join yourtable
    on vt_merged.txn_id = yourtable.txn_id
group by 1
这可能会做得更干净一些,但它会让你找到你想要的东西。

这是@S-Man的as-working查询:

WITH cte AS
 (
   SELECT Customer_id,
      Trim(PART_N) ||'/' || PART_C AS all_parts
   FROM tab
 )
SELECT
   part, -- if part should be numeric: Cast(part AS INT) 
   Count(DISTINCT Customer_id)
FROM TABLE (StrTok_Split_To_Table(cte.Customer_id, cte.all_parts, '/')
     RETURNS (Customer_id VARCHAR(10), tokennum INTEGER, part VARCHAR(30))) AS t
GROUP BY 1

您使用的是哪种数据库管理系统?(MySQL、Postgres、Oracle、MS SQL Server等)。尽管我建议将您的数据库重新设计为第三种标准形式。@S-Man in teradata