2017-06-13 75 views
0

我需要更新我的结果列值在整个用户如果用户没有做出连续4次购买之间没有收到奖金。如何才能做到这一点。请参阅下面我的代码.....更新柱连续4名购买

-- drop table #Test 
CREATE TABLE #Test (UserID int, TheType VARCHAR(10), TheDate DATETIME, Result VARCHAR(10)) 
INSERT INTO #Test 
SELECT 1234, 'Bonus', GETDATE(), NULL 
UNION 
SELECT 1234, 'Purchase', GETDATE()-1, NULL 
UNION 
SELECT 1234, 'Purchase', GETDATE()-2, NULL 
    UNION 
SELECT 1234, 'Purchase', GETDATE()-3, NULL 
    UNION 
SELECT 1234, 'Purchase', GETDATE()-4, NULL 
    UNION 
SELECT 1234, 'Bonus', GETDATE()-5, NULL 
    UNION 
SELECT 1234, 'Purchase', GETDATE()-6, NULL 
    UNION 
SELECT 1234, 'Bonus', GETDATE()-7, NULL 

SELECT * FROM #Test ORDER BY TheDate 

再次,请注意,购买的需要是连续的(通过TheDate)

回答

2

您可以按以下:

;WITH CTE1 
AS 
(
    SELECT 
     ROW_NUMBER() OVER (ORDER BY TheDate) RowId, 
     ROW_NUMBER() OVER (PARTITION BY UserID,TheType ORDER BY TheDate) PurchaseRowId, 
     * 
    FROM @Test 

), CTE2 
AS 
(
    SELECT 
     MIN(A.RowId) MinId, 
     MAX(A.RowId) MaxId 
    FROM 
     CTE1 A 
    GROUP BY  
     A.TheType, 
     A.RowId - A.PurchaseRowId 
) 


SELECT   
    A.UserID , 
    A.TheType , 
    A.TheDate , 
    CASE WHEN B.MinId IS NULL THEN NULL ELSE 'YES' END Result 
FROM 
    CTE1 A LEFT JOIN 
    CTE2 B ON A.RowId >= B.MinId AND A.RowId <= B.MaxId AND (B.MaxId - B.MinId) > 2  
    --AND A.TheType = 'Purchase'  
ORDER BY A.TheDate 

结果:

UserID  TheType TheDate     Result 
----------- ---------- ----------------------- - ------ 
1234  Bonus  2017-06-06 11:06:03.130 NULL 
1234  Purchase 2017-06-07 11:06:03.130 NULL 
1234  Bonus  2017-06-08 11:06:03.130 NULL 
1234  Purchase 2017-06-09 11:06:03.130 YES 
1234  Purchase 2017-06-10 11:06:03.130 YES 
1234  Purchase 2017-06-11 11:06:03.130 YES 
1234  Purchase 2017-06-12 11:06:03.130 YES 
1234  Bonus  2017-06-13 11:06:03.130 NULL 
0

首先,你必须派生列组,然后由该组(有= 4)和内部连接与ori金奈表。

drop table if exists #Test; 

create table #Test 
(
UserID int 
, TheType varchar(10) 
, TheDate date 
, Result varchar(10) 
); 

insert into #Test 
select 1234, 'Bonus', getdate(), null 
union 
select 1234, 'Purchase', getdate() - 1, null 
union 
select 1234, 'Purchase', getdate() - 2, null 
union 
select 1234, 'Purchase', getdate() - 3, null 
union 
select 1234, 'Purchase', getdate() - 4, null 
union 
select 1234, 'Bonus', getdate() - 5, null 
union 
select 1234, 'Purchase', getdate() - 6, null 
union 
select 1234, 'Bonus', getdate() - 7, null; 

drop table if exists #temp; 

select 
    * 
    , lag(t.TheDate, 1) over (order by t.TheDate) as Lag01 
    , lag(t.TheType, 1) over (order by t.TheDate) as LagType 
into 
    #temp 
from #Test t; 

with cteHierarchy 
as 
(
    select 
      UserID 
     , TheType 
     , TheDate 
     , Result 
     , Lag01 
     , t.TheDate as Root 
    from #temp t 
    where t.LagType <> t.TheType 
    union all 
    select 
     t.UserID 
     , t.TheType 
     , t.TheDate 
     , t.Result 
     , t.Lag01 
     , cte.Root as Root 
    from #temp t 
     inner join cteHierarchy cte on t.Lag01 = cte.TheDate 
             and t.TheType = cte.TheType 
) 
update test 
set 
    Result = 4 
from (
    select 
     t.Root 
     , count(t.UserID) as Cnt 
     , t.UserID 
    from cteHierarchy t 
    group by t.UserID, t.Root 
    having count(t.UserID) = 4 
) tt 
    inner join #Test test on tt.UserID = test.UserID 


select * from #Test t 
order by t.TheDate;