识别SQL列中某些值的交互

时间:2015-08-28 18:33:19

标签: sql-server

我有以下表格

CustomerTable

 CustomerID   |   Year_Date    |   Score    |   Tier   
-------------------------------------------------------------
      100     |      2014      |       50   |  Beginner
      100     |      2014      |       25   |  Naieve
      100     |      2014      |      100   |  Pro
      100     |      2014      |       60   |  Mediocre
      100     |      2014      |       70   |  Advanced
      100     |      2015      |       20   |  Poor
      100     |      2015      |        5   |  Unacceptable
      200     |      2015      |      100   |  Pro
      200     |      2015      |      150   |  SuperPro
      200     |      2015      |      180   |  Top 

互动表

TierInteraction   | AdditionalScore
----------------------------------
Pro_Advanced      |         75 
Beginner_Mediocre |         50
Pro_SuperPro      |         80
Pro_Top           |        100
Mediocre_Poor     |         10
Poor_Unacceptable |          5  

现在,从Customer Table中的Tier列,我需要确定是否存在来自InteractionTable的任何TierInteraction

示例 - 存在以下交互

对于2014年的客户100

  1. Pro_Advanced
  2. Beginner_Mediocre
  3. 对于2015年的客户100

    1. Poor_Unacceptable
    2. 对于2015年的客户200

      1. Pro_SuperPro
      2. Top_Pro
      3. 以下是我需要结果表的方法

        结果表

        CustomerID | Year_Date | Score |   Tier       | TierInteraction   | AdditionalScore  
        --------------------------------------------------------------------------------
           100     | 2014      |  50   |  Beginner    | Beginner_Mediocre |    50
           100     | 2014      |  25   |  Naive       | NULL              |     0
           100     | 2014      | 100   |  Pro         | Pro_Advanced      |    75
           100     | 2014      |  60   |  Mediocre    | Beginner_Mediocre |    50
           100     | 2014      |  70   |  Advanced    | Pro_Advanced      |    75
           100     | 2015      |  20   |  Poor        | Poor_Unacceptable |     5
           100     | 2015      |   5   |  Unacceptable| Poor_Unacceptable |     5
           200     | 2015      | 100   |  Pro         | Pro_SuperPro      |    80
           200     | 2015      | 150   |  SuperPro    | Pro_SuperPro      |    80
           200     | 2015      | 180   |  Top         | Pro_Top           |   100  
        

        业务规则:

        • 应按照每年每位客户确定相互作用
        • 一行可以与其他行进行多次交互。(客户200 Pro与SuperPro以及Top相互作用 两次互动都应至少考虑一次。
        • 互动顺序无关紧要。 Pro_Advanced与Advanced_Pro
        • 相同

1 个答案:

答案 0 :(得分:1)

你在这里:

declare @Customer TABLE(CustomerID INT,Year_Date INT, Score INT, Tier VARCHAR(100));
INSERT INTO @customer VALUES   
(100,2014,50,'Beginner')
,(100,2014,25,'Naieve')
,(100,2014,100,'Pro')
,(100,2014,60,'Mediocre')
,(100,2014,70,'Advanced')
,(100,2015,20,'Poor')
,(100,2015,5,'Unacceptable')
,(200,2015,100,'Pro')
,(200,2015,150,'SuperPro')
,(200,2015,180,'Top');

declare @TierInteraction TABLE(TierInteraction VARCHAR(100),AdditionalScore INT);
insert into @TierInteraction VALUES
 ('Pro_Advanced',75)
,('Beginner_Mediocre',50)
,('Pro_SuperPro',80)
,('Pro_Top',100)
,('Mediocre_Poor',10)
,('Poor_Unacceptable',5);

WITH TierInteractionResolved AS
(
    SELECT ti.*
          ,tiParts.*
    FROM @TierInterAction AS ti
    CROSS APPLY(SELECT CAST('<root><r>' +  REPLACE(ti.TierInteraction,'_','</r><r>') + '</r></root>' AS XML)) AS tiSplit(ti)
    CROSS APPLY
    (
        SELECT tiSplit.ti.value('/root[1]/r[1]','varchar(max)') AS firstPart
              ,tiSplit.ti.value('/root[1]/r[2]','varchar(max)') AS secondPart
    ) AS tiParts
)
SELECT * 
FROM @Customer AS c
CROSS APPLY
(
    SELECT * 
    FROM TierInteractionResolved AS tir
    WHERE (c.Tier=tir.firstPart AND EXISTS(SELECT x.* FROM @customer AS x WHERE tir.secondPart=x.Tier AND x.Year_Date=c.Year_Date))
       OR (c.Tier=tir.secondPart AND EXISTS(SELECT x.* FROM @customer AS x WHERE tir.firstPart=x.Tier AND x.Year_Date=c.Year_Date))

) AS FinalTiers
ORDER BY c.CustomerID,c.Year_Date