获取用户使用特定优惠的次数

时间:2019-07-09 16:21:18

标签: sql sql-server

我有一个表,其中提供有关特定用户何时使用报价的信息。它有3列

Date:报价的使用日期

user_id:特定用户的标识符

txn_id:用户使用要约时的交易ID。在表中它始终是唯一的。

此优惠使特定用户可以使用5次。

我想知道每个日期处于使用优惠阶段的用户数量。

例如 在第1天,可能有3个用户使用过一次优惠(redemption_1),2个用户可能使用过两次优惠(redemption_2)。

现在,在第2天,可能有来自第1天的用户(重复用户),以及首次使用优惠的用户(新用户)。

对于第2天的新用户,逻辑与第1天的用户相同。(可能是2个新用户使用此优惠1次(redemption_1),3个新用户使用3次该优惠(redemption_3))< / p>

但是对于现在的重复用户,我想累加前一天的使用情况。

例如 在第1天,有3个用户曾经使用过一次优惠(redemption_1),但在第2天,如果他们再使用一次,则应计入redemption_2。(而不是在redemption_1中,因为自优惠开始以来他们已经第二次使用该优惠了。 /或最后使用)

通过这种方式,我想继续累计用户使用商品的次数,并计算1次(redemption_1),2次(redemption_2)等使用商品的用户数,以此类推每个日期

+------------+---------+------------+
|    Date    | user_id |   txn_id   |
+------------+---------+------------+
| 2019-06-04 |       1 | 1ACSA0-ABA |
| 2019-06-04 |       2 | 1BEAA0-CSC |
| 2019-06-04 |       3 | 1AGHF0-CBA |
| 2019-06-04 |       1 | 1AVFA0-GAA |
| 2019-06-05 |       1 | 1BCFA0-AAA |
| 2019-06-05 |       1 | 1AVFB0-GAC |
| 2019-06-05 |       2 | 1AVFA0-GVA |
| 2019-06-05 |       4 | 1AVFA0-GVB |
| 2019-06-05 |       5 | 1AVFA0-BCF |
| 2019-06-06 |       6 | 1AGHF0-CCA |
| 2019-06-06 |       1 | 1BXHF0-CCA |
| 2019-06-06 |       2 | 1AGHF0-CBG |
| 2019-06-06 |       3 | 1AGHF0-CAW |
| 2019-06-06 |       2 | 1AGHF0-CTU |
+------------+---------+------------+

所需的输出

+------------+--------------+--------------+--------------+--------------+--------------+
|    Date    | redemption_1 | redemption_2 | redemption_3 | redemption_4 | redemption_5 |
+------------+--------------+--------------+--------------+--------------+--------------+
| 2019-06-04 |            2 |            1 |            0 |            0 |            0 |
| 2019-06-05 |            2 |            1 |            0 |            1 |            0 |
| 2019-06-06 |            1 |            1 |            0 |            1 |            1 |
+------------+--------------+--------------+--------------+--------------+--------------+

我将带您逐步了解输出内容,以便更好地理解

在日期为2019-06-04的第一行中,有两个用户使用过一次优惠(2,3),一个用户使用过两次优惠(1)

在日期为2019-06-05的行中,有2个用户使用了一次要约(4,5)。请注意,他们之前从未使用过要约,所以他们算为redemption_1

在同一行中,有1个用户使用了2次优惠(2:在2019-06-04上一次,然后在2019-06-05上一次),因此他被计为redemption_2

在同一行中,有1个用户使用了4次优惠(1:两次在2019-06-04上使用,然后再次在2019-06-05上使用两次),因此他被计为redemption_4

以日期为2019-06-06的行依此类推

请让我知道任何澄清

2 个答案:

答案 0 :(得分:1)

这不是效率的典范,但确实有效。

测试数据:

Create Table offer_used(date DateTime, user_id Int, txn_id Varchar(50))

Insert Into dbo.offer_used (date,
                            user_id,
                            txn_id)
Values
('2019-06-04', 1, '1ACSA0-ABA'),
('2019-06-04', 2, '1BEAA0-CSC'),
('2019-06-04', 3, '1AGHF0-CBA'),
('2019-06-04', 1, '1AVFA0-GAA'),
('2019-06-05', 1, '1BCFA0-AAA'),
('2019-06-05', 1, '1AVFB0-GAC'),
('2019-06-05', 2, '1AVFA0-GVA'),
('2019-06-05', 4, '1AVFA0-GVB'),
('2019-06-05', 5, '1AVFA0-BCF'),
('2019-06-06', 6, '1AGHF0-CCA'),
('2019-06-06', 1, '1BXHF0-CCA'),
('2019-06-06', 2, '1AGHF0-CBG'),
('2019-06-06', 3, '1AGHF0-CAW'),
('2019-06-06', 2, '1AGHF0-CTU')

查询:

; With 
Dates As (Select Distinct date From dbo.offer_used OU),
Users As (Select user_id, FirstTime = Min(date) From dbo.offer_used OU Group By user_id),
UserCounts As (Select 
                 Dates.date,
                 Users.user_id,
                 Users.FirstTime,
                 UsedCount = (Select Count(*) From dbo.offer_used As Used
                              Where Used.date <= Dates.date
                                And Used.user_id  = Users.user_id)
               From 
                 Dates 
                 Cross Join Users)
Select 
  date = UserCounts.date,
  [first time today] = Sum(Case When UserCounts.date = UserCounts.FirstTime
                                 And UserCounts.UsedCount = 1 Then 1 Else 0 End),
  [2 times total] = Sum(Case When UserCounts.UsedCount = 2 Then 1 Else 0 End),
  [3 times total] = Sum(Case When UserCounts.UsedCount = 3 Then 1 Else 0 End),
  [4 times total] = Sum(Case When UserCounts.UsedCount = 4 Then 1 Else 0 End),
  [5 times total] = Sum(Case When UserCounts.UsedCount = 5 Then 1 Else 0 End),
  [bonus: never]  = Sum(Case When UserCounts.UsedCount = 0 Then 1 Else 0 End)
From UserCounts
Group By UserCounts.date
Order By UserCounts.date

结果:

date        first time today 2 times total 3 times total 4 times total 5 times total bonus: never
----------- ---------------- ------------- ------------- ------------- ------------- ------------
2019-06-04  2                1             0             0             0             3
2019-06-05  2                1             0             1             0             1
2019-06-06  1                1             0             1             1             0

答案 1 :(得分:0)

我认为您需要条件聚合:

select t.date,
       sum(case when seqnum = 1 then 1 else 0 end) as redemption_1,
       sum(case when seqnum = 2 then 1 else 0 end) as redemption_2,
       sum(case when seqnum = 3 then 1 else 0 end) as redemption_3,
       sum(case when seqnum = 4 then 1 else 0 end) as redemption_4,
       sum(case when seqnum = 5 then 1 else 0 end) as redemption_5
from (select t.*, row_number() over (partition by user_id order by date) as seqnum
      from table t
     ) t
group by t.date
order by t.date