SQL-通过“产品”列识别客户业务范围

时间:2019-05-03 18:54:26

标签: sql tsql netezza

我有一个表,其中包含客户信息-他们的客户编号,产品等。我想根据他们拥有的产品来确定每个客户所属的业务范围。每个客户可以有1个或更多行(每行表示一个客户及其产品)。看起来像这样:

Customer #  Product
-----------------------------------------   
000000001   BROKERAGE   
000000001   CHECKING
000000001   CREDIT CARD 
000000001   SAVING
000000001   LIFE INSURANCE  

现在,这只是一个客户,但是我有关于哪些产品属于哪些业务领域的规则,例如:

银行:检查,信用卡,储蓄

投资:经纪,共同基金

人寿保险:人寿保险

我要做的是查看整个表,按客户说,如果该客户拥有任何银行产品,我想创建一个新列“ Bank”,并在每一行的该列中输入“ Y”该客户的故事-这将告诉我,无论我要看的是哪一行,该客户都是银行客户。最后,我想要一个关于所有这些LOB的专栏,所以最终产品看起来像这样:

Customer #  Product          Bank    Investments    Life
---------------------------------------------------------
000000002   BROKERAGE          Y          Y           N
000000002   CHECKING           Y          Y           N
000000002   CREDIT CARD        Y          Y           N
000000002   SAVING             Y          Y           N

此处的逻辑是,“银行”和“投资”列为“ Y”,因为客户从每个LOB中至少拥有一种产品。但是,该客户没有人寿保险单,因此该客户的整个列为“ N”。

很明显,我有多个客户,所以我试图用一个case语句来完成此操作,但是我使用的只是查看当前行的列,因此只有一行匹配的地方,我只能得到“ Y” 。我想要匹配该客户的任何行...我想也许是对PARTITION或GROUP BY做点什么,但我不知道从哪里开始。...有什么想法或提示吗?

3 个答案:

答案 0 :(得分:1)

尝试这样的事情:

SELECT tbl.customer, tbl.product,
case when temp.Bank>0 then 'Y' else 'N' end as Bank,
case when temp.Investment>0 then 'Y' else 'N' end as Investment,
case when temp.Insurance>0 then 'Y' else 'N' end as Insurance
FROM tbl
LEFT JOIN
(SELECT customer,
sum(case when Product in ('CHECKING', 'CREDIT CARD', 'SAVINGS') then 1 else 0 end) as Bank, 
sum(case when Product in ('BROKERAGE','MUTUAL FUNDS') then 1 else 0 end) as Investment,
sum(case when Product in ('LIFE INSURANCE') then 1 else 0 end) as Insurance
FROM tbl
GROUP BY Customer) tmp
on tmp.customer=tbl.customer

答案 1 :(得分:1)

这应该做到...快速,简单和快速的解决方案。

DECLARE @Products table
(
        CustomerNumber int
    ,   Product nvarchar(50)
)

INSERT @Products VALUES (1, 'BROKERAGE')
INSERT @Products VALUES (1, 'CHECKI[NG')
INSERT @Products VALUES (1, 'CREDIT CARD')
INSERT @Products VALUES (2, 'SAVINGS')
INSERT @Products VALUES (2, 'LIFE INSURANCE')


;WITH
ProductTypes AS
(
    SELECT
            CustomerNumber
        ,   SUM(CASE WHEN Product IN ('CHECKING', 'CREDIT CARD', 'SAVINGS') THEN 1 ELSE 0 END) AS Bank
        ,   SUM(CASE WHEN Product IN ('BROKERAGE', 'MUTUAL FUND') THEN 1 ELSE 0 END) AS Investments
        ,   SUM(CASE WHEN Product IN ('LIFE INSURANCE') THEN 1 ELSE 0 END) AS Life
    FROM    @Products
    GROUP BY CustomerNumber
)
SELECT
        Products.CustomerNumber
    ,   Products.Product
    ,   CASE WHEN Bank > 0 THEN 'Y' ELSE 'N' END AS Bank
    ,   CASE WHEN Investments > 0 THEN 'Y' ELSE 'N' END AS Investments
    ,   CASE WHEN Life > 0 THEN 'Y' ELSE 'N' END AS Life
FROM    @Products AS Products
LEFT JOIN ProductTypes ON (ProductTypes.CustomerNumber = Products.CustomerNumber)

已对该版本进行了修改,以考虑到您在进行初始联接以获取源表的评论。

DECLARE @Customer table
(
        CustomerNumber int
)

INSERT @Customer VALUES (1)
INSERT @Customer VALUES (2)

DECLARE @Products table
(
        CustomerNumber int
    ,   Product nvarchar(50)
)

INSERT @Products VALUES (1, 'BROKERAGE')
INSERT @Products VALUES (1, 'CHECKI[NG')
INSERT @Products VALUES (1, 'CREDIT CARD')
INSERT @Products VALUES (2, 'SAVINGS')
INSERT @Products VALUES (2, 'LIFE INSURANCE')


;WITH
CustomerProducts AS
(
    SELECT
            Customer.CustomerNumber
        ,   Products.Product
    FROM @Customer AS Customer
    LEFT JOIN @Products AS Products ON (Products.CustomerNumber = Customer.CustomerNumber)
)
, ProductTypes AS
(
    SELECT
            CustomerNumber
        ,   SUM(CASE WHEN Product IN ('CHECKING', 'CREDIT CARD', 'SAVINGS') THEN 1 ELSE 0 END) AS Bank
        ,   SUM(CASE WHEN Product IN ('BROKERAGE', 'MUTUAL FUND') THEN 1 ELSE 0 END) AS Investments
        ,   SUM(CASE WHEN Product IN ('LIFE INSURANCE') THEN 1 ELSE 0 END) AS Life
    FROM    CustomerProducts
    GROUP BY CustomerNumber
)
SELECT
        CustomerProducts.CustomerNumber
    ,   CustomerProducts.Product
    ,   CASE WHEN Bank > 0 THEN 'Y' ELSE 'N' END AS Bank
    ,   CASE WHEN Investments > 0 THEN 'Y' ELSE 'N' END AS Investments
    ,   CASE WHEN Life > 0 THEN 'Y' ELSE 'N' END AS Life
FROM    CustomerProducts
LEFT JOIN ProductTypes ON (ProductTypes.CustomerNumber = CustomerProducts.CustomerNumber)

答案 2 :(得分:0)

尽管以上两个解决方案都很有帮助,但最终,我要寻找的解决方案要简单得多。我发现有一篇帖子描述了类似的问题,建议的解决方案是在该列上使用MAX(),并按ID /用户/任何内容进行分组。所以,如果我有以下内容:

Customer #  Product
----------------------------   
000000001   BROKERAGE   
000000001   CHECKING
000000001   CREDIT CARD 
000000001   SAVING
000000001   LIFE INSURANCE 
000000002   BROKERAGE   
000000002   LIFE INSURANCE 

我使用CASE语句为“银行”,“投资”和“人寿”创建适当的列,以产生以下结果:

Customer #  Product          Bank    Investments    Life
---------------------------------------------------------
000000001   BROKERAGE          N          Y           N
000000001   CHECKING           Y          N           N
000000001   CREDIT CARD        Y          N           N
000000001   SAVING             Y          N           N
000000002   BROKERAGE          N          Y           N
000000002   LIFE INSURANCE     N          N           Y

因此,现在我基于什么行知道该产品属于哪个LOB,但是由于我只想总结每个客户所属的LOB(是/否)。在这种情况下,我知道1号客户是Bank and Investments的一部分(该客户至少拥有Bank and Investments的一种产品)。 2号客户只有投资和人寿保险,而没有银行产品。因此,我想看看:

Customer #  Bank    Investments    Life
---------------------------------------------------------
000000001     Y          Y           N
000000002     N          Y           Y

我这样做是通过根据客户#分组的先前表/结果执行另一个SELECT,并根据需要对每个Y / N列执行MAX:

SELECT CUST_NUMBER,
MAX(BANK) AS BANK,
MAX(INVENTMENTS) AS INVESTMENTS,
MAX(LIFE) as LIFE
FROM
( ORIGINAL QUERY TO GET PRIOR TABLE
  GROUP BY CUST_NUMBER
) A
ON CUST_NUMBER = A.CUST_NUMBER

如果与该客户编号相关的任何行的每一列都存在,则为您提供Y。如果全为“ Y”,则得到一个“ Y”,如果至少有1个“ Y”,则得到一个“ Y”。如果该客户的列对于该列中的所有值均为“ N”,则将获得“ N”。我在几种情况下进行了测试,效果很好。希望这对遇到相同问题的其他人有所帮助。