SQL优先于忠诚度积分

T.F*_*ung 5 sql sql-server fifo

开发商和分析师.我有一些SQL经验,并使用类似的帖子.然而,这是一个更小的利基.提前谢谢你的帮助.

我有以下数据集(编辑.道歉)

数据集

建立

CREATE TABLE CustomerPoints
(
    CustomerID INT,
    [Date]     Date,
    Points     INT
)

INSERT INTO CustomerPoints
VALUES
    (1, '20150101', 500),
    (1, '20150201', -400),
    (1, '20151101', 300),
    (1, '20151201', -400)
Run Code Online (Sandbox Code Playgroud)

并需要将其变为(已编辑.上表中的数字不正确) 在此输入图像描述

任何积分的积分都是积分,而积极积分则是兑换积分.由于FIFO(第一个概念中的第一个),在第二批花费的点数(-400)中,其中100个是从20150101(英国格式)获得的积分和20151101中的300积分中获得的.

目标是为每个客户计算在x和y个月收入中花费的点数.再次,谢谢你的帮助.

Mtw*_*ark 5

我已经在这里这里回答了类似的问题

您需要将单个单位赚取和兑换的积分进行爆炸,然后将它们配对,因此每个赚取的积分都会与兑换的积分相匹配。

对于这些匹配行中的每一个,计算从收入到赎回所经过的月份,然后将其汇总。

对于 FN_NUMBERS(n) 它是一个计数表,请查看我在上面链接的其他答案。

;with
p as (select * from CustomerPoints),
e as (select * from p where points>0),
r as (select * from p where points<0),
ex as (
    select *, ROW_NUMBER() over (partition by CustomerID order by [date] ) rn
    from e
    join FN_NUMBERS(1000) on N<= e.points
),
rx as (
    select *, ROW_NUMBER() over (partition by CustomerID order by [date] ) rn
    from r
    join FN_NUMBERS(1000) on N<= -r.points
),
j as (
select ex.CustomerID, DATEDIFF(month,ex.date, rx.date) mm
from ex
join rx on ex.CustomerID = rx.CustomerID and ex.rn = rx.rn and rx.date>ex.date
)
-- use this select to see points redeemed in current and past semester
select * from j  join (select 0 s union all select 1 s ) p on j.mm >= (p.s*6)+(p.s) and j.mm < p.s*6+6 pivot (count(mm) for s in ([0],[2])) p order by 1, 2

-- use this select to see points redeemed with months detail
--select * from j pivot (count(mm) for mm in ([0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) p order by 1

-- use this select to see points redeemed in rows per month
--select CustomerID, mm, COUNT(mm) PointsRedeemed   from j  group by CustomerID, mm order by 1
Run Code Online (Sandbox Code Playgroud)

默认查询的输出,0 是 0-6 个月,1 是 7-12(赎回年龄以月为单位)

CustomerID  0   1
1           700 100
Run Code Online (Sandbox Code Playgroud)

第二个查询的输出,0..12 是以月为单位的赎回年龄

CustomerID  0   1   2   3   4   5   6   7   8   9   10  11  12
1           0   700 0   0   0   0   0   0   0   0   0   100 0
Run Code Online (Sandbox Code Playgroud)

第三个查询的输出是以月为单位的赎回年龄

CustomerID  mm  PointsRedeemed
1           1   700
1           11  100
Run Code Online (Sandbox Code Playgroud)

再见