Had a brief search online to see if an answer to this already existed. Couldn't find anything that tackled this particular situation (which was a surprise, as I would have assumed it was fairly common).
Basically I have a table that records registrations with a service, along with the ID of the client registering, and the start and end dates of the registration. See below for an example of the table structure:
Reg ID | Client ID | Reg Start | Reg End
R6 C1 01-06-2016 Null
R5 C2 20-05-2016 02-06-2016
R4 C2 14-03-2016 11-05-2016
R3 C1 10-03-2016 05-05-2016
R2 C2 28-01-2016 02-02-2016
R1 C2 10-11-2015 23-12-2015
What I want to do, is pull the records from the table but also add a column that returns a count of how many previous registrations are in the table with the same client ID for each record. For the sake of clarity, I only want to count registrations for each record that have the same client ID and have a start date less than that of the record.
As such, a successful query would return the following output:
Reg ID | Client ID | Reg Start | Reg End | # previous reg
R6 C1 01-06-2016 Null 1
R5 C2 20-05-2016 02-06-2016 3
R4 C2 14-03-2016 11-05-2016 2
R3 C1 10-03-2016 05-05-2016 0
R2 C2 28-01-2016 02-02-2016 1
R1 C2 10-11-2015 23-12-2015 0
Has anyone had previous experience of doing this who could offer a viable solution?
My initial thought process was to create a sub query that would count registrations grouped by client ID, and then join this to my main query using client ID. For example:
SELECT
t1.reg_id
t1.client_id
t1.reg_start
t1.reg_end
FROM registrations t1
JOIN
(SELECT
client_id
count(reg_id)
FROM registrations
GROUP BY client_id) t2
ON t1.client_id = t2.client_id
However, this would return a count of the total registrations for a given client per record, where as I specifically require the previous registrations.
Any input that the hive mind could provide would be much appreciated. I think I've hit a bit of a wall with my currently quite limited SQL knowledge here :/
Also I should probably mention that I'm using an Oracle database!
You can do this with row_number()
:
select r.*,
(row_number() over (partition by client_id order by reg_start) - 1) as cnt
from registrations r;
This can be done with a window function and a running sum:
select reg_id, client_id, reg_start, reg_end,
count(*) over (partition by client_id order by reg_start) - 1 as previous_reg
from registrations
order by reg_start desc;
In SQL Server you can use the following query:
SELECT [Reg ID], [Client ID], Reg_Start, Reg_End,
COUNT(*) OVER (PARTITION BY [Client ID] ORDER BY Reg_Start) - 1
FROM mytable
COUNT
, when applied with an ORDER BY
clause, returns the running total of records count. If this is available in Oracle, then it should return the value you want.
The easiest way, in my opinion, is to build a subquery in the SELECT
statement of main query, as follow:
SELECT
t1.*,
(
SELECT COUNT(*)
FROM registrations t2
WHERE t2.client_id = t1.client_id
AND t2.reg_start < t1.reg_start
) AS previous_reg
FROM registrations t1
ORDER BY reg_id DESC
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.