在指定时间之前计数COUNT次,是否可以自我加入?

时间:2020-05-04 06:22:57

标签: sql sql-server-2016 self-join

为简单起见,我们假设我有两个表:

billing,其中包含以下字段bill_id(主键,唯一键,整数),person_idbill_datebilling_detail包含bill_idservice_type

首先,我想要一个清单(person_id),这些清单在给定时期内针对给定范围的服务收费,所以简单

SELECT billing.person_id, billing.bill_date
FROM   billing
INNER JOIN billing_detail ON billing.bill_id = billing_detail.bill_id
WHERE      billing_detail.service_type IN (list of services)
  AND      billing.bill_date between some_date and another_date

我现在想做的是,还要显示给定客户在给定日期之前针对相同范围的服务付费的次数。

假设billing表包含:

1  | 1 | 1/1/2020
2  | 1 | 1/2/2020
3  | 1 | 1/3/2020
4  | 1 | 1/4/2020
4  | 1 | 2/4/2020

billing_detail表包含:

1  |  A
2  |  B
3  |  A
4  |  B
5  |  A

因此,如果我要在1月至4月期间针对服务类型A为客户1运行报告,则预期结果将是

1 | 1/1/2020 | 0 (no A type service prior to this date)
1 | 1/3/2020 | 1 (One A type service prior to this date)
1 | 2/4/2020 | 2 (Two A type services prior ot this date).

这可能涉及到两张桌子上的某种自我连接,但是我疲倦的鸟脑目前似乎还无法提出答案。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

您可以在ROW_NUMBER()person_id上使用service_type来获得所需的结果,减去1即可将值从0开始:

SELECT person_id, bill_date, service_type,
       ROW_NUMBER() OVER (PARTITION BY person_id, service_type ORDER BY bill_date) - 1 AS prior_services
FROM billing b
JOIN billing_detail bd ON bd.bill_id = b.bill_id

这将为您提供所有服务类型的数据:

person_id   bill_date   service_type    prior_services
1           2020-01-01  A               0
1           2020-01-03  A               1
1           2020-02-04  A               2
1           2020-01-02  B               0
1           2020-01-04  B               1

要限制服务类型,请添加

WHERE service_type = 'A'

或类似的

Demo on dbfiddle