问题
For simplicity let's assume I have two tables:
billing
with the following fields bill_id
(primary, unique key, int), person_id
, bill_date
, and
billing_detail
containing bill_id
and service_type
.
First of all I would like a list of clients (person_id
) who were billed for a given range of services in a given period, so simply
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
What I would like to do now is to also show how many times a given client was billed for the same range of services PRIOR to the given date.
Say the billing
table contains:
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
And the billing_detail
table contains:
1 | A
2 | B
3 | A
4 | B
5 | A
So if I was to run a report for client 1 for the period from January to April for service type A, the expected outcome would be
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).
This probably involves some kind of self-join on both tables but my tired bird-brain can't seem to come up with the answer at the moment. Any help would be appreciated.
回答1:
You can use ROW_NUMBER()
over the person_id
and service_type
to get the result you want, subtracting one to start the values at 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
This will give you data for all service types:
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
To restrict the service type, add a
WHERE service_type = 'A'
or similar.
Demo on dbfiddle
来源:https://stackoverflow.com/questions/61586269/count-number-of-times-prior-to-specified-time-self-join