This doesn't directly answer the question, but I'm aiming to explain why what you are trying isn't working as you expect.
Your issue is caused by the PARTITION
. If you remove the non-unique columns from your PARTITION
clause, you are left with afdelingscode
. So in simple terms your PARTITION
is grouping the data like so:
RD8-GH Endo
RD8-GH MAU
RD8-GH MAU
RD8-GH Ward 08
RD8-GH Ward 08
RD8-GH Ward 08
The ORDER BY
clause determines the order within your PARTITION
, so again removing the non-unique columns gives you ORDER BY OntslagDatumTijd
, which produces this, where it's ordered by the date column, note the partitions are still separated by afdelingscode
:
afdelingscode OntslagDatumTijd
RD8-GH Endo 2014-09-09 09:06:00.000
RD8-GH MAU 2014-09-01 14:50:00.000
RD8-GH MAU 2014-09-02 19:32:00.000
RD8-GH Ward 08 2014-09-03 17:12:00.000
RD8-GH Ward 08 2014-09-17 17:00:00.000
RD8-GH Ward 08 2014-10-01 17:15:00.000
The ranking is then applied to these partitions. The output of this becomes:
rnk afdelingscode OntslagDatumTijd
1 RD8-GH Endo 2014-09-09 09:06:00.000
1 RD8-GH MAU 2014-09-01 14:50:00.000
2 RD8-GH MAU 2014-09-02 19:32:00.000
1 RD8-GH Ward 08 2014-09-03 17:12:00.000
2 RD8-GH Ward 08 2014-09-17 17:00:00.000
3 RD8-GH Ward 08 2014-10-01 17:15:00.000
So it's being ranked according to how you have specified, the problem in your output is because at the end of your select (taking out the non-unique columns) is ordering by the date column OntslagDatumTijd
, which gives you:
rnk afdelingscode OntslagDatumTijd
1 RD8-GH MAU 2014-09-01 14:50:00.000
2 RD8-GH MAU 2014-09-02 19:32:00.000
1 RD8-GH Ward 08 2014-09-03 17:12:00.000
1 RD8-GH Endo 2014-09-09 09:06:00.000
2 RD8-GH Ward 08 2014-09-17 17:00:00.000
3 RD8-GH Ward 08 2014-10-01 17:15:00.000
I will continue to look at this if the other answer that is posted doesn't meet your requirements.
Reference:
OVER Clause
PARTITION BY Divides the query result set into partitions. The window
function is applied to each partition separately and computation
restarts for each partition.
ORDER BY clause Defines the logical order of the rows within each
partition of the result set. That is, it specifies the logical order
in which the window functioncalculation is performed.
Here's a potential solution that may have performance issues with the size of the data you are using, but you can test it:
-- sets up your dummy data
CREATE TABLE #t_opnames
(
Opnamenummer INT ,
Patient_ID INT ,
afdelingscode NVARCHAR(20) ,
Opnametype NVARCHAR(20) ,
Specialismen NVARCHAR(20) ,
OntslagDatumTijd DATETIME
);
INSERT INTO #t_opnames
( Opnamenummer, Patient_ID, afdelingscode, Opnametype, Specialismen,
OntslagDatumTijd )
VALUES ( 2983800, 100006, 'RD8-GH MAU', 'Inpatient-E', 'GM',
'2014-09-01 14:50:00.000' ),
( 2983800, 100006, 'RD8-GH MAU', 'Inpatient-E', 'GM',
'2014-09-02 19:32:00.000' ),
( 2983800, 100006, 'RD8-GH Ward 08', 'Inpatient-E', 'GM',
'2014-09-03 17:12:00.000' ),
( 2983800, 100006, 'RD8-GH Endo', 'Inpatient-E', 'GM',
'2014-09-09 09:06:00.000' ),
( 2983800, 100006, 'RD8-GH Ward 08', 'Inpatient-E', 'GM',
'2014-09-17 17:00:00.000' ),
( 2983800, 100006, 'RD8-GH Ward 08', 'Inpatient-E', 'GM',
'2014-10-01 17:15:00.000' )
-- I've added a row number to your data to enable iteration over the data
SELECT ROW_NUMBER() OVER ( ORDER BY OntslagDatumTijd ) AS rn ,
*
INTO #temp
FROM #t_opnames
ORDER BY OntslagDatumTijd
-- this will iterate over the rows and apply the rankings
;WITH cte AS (
SELECT *, 1 AS rnk
FROM #temp
WHERE rn = 1
UNION ALL
SELECT t.*, CASE WHEN cte.afdelingscode = t.afdelingscode
THEN cte.rnk + 1
ELSE 1
END AS rnk
FROM #temp t
INNER JOIN cte ON cte.rn +1 = t.rn
)
SELECT * FROM cte
DROP TABLE #t_opnames
DROP TABLE #temp
You will hit the MAXRECURSION
limit for a larger dataset, for which you need to modify the limit using the following after the final SELECT
:
SELECT * FROM cte
OPTION (MAXRECURSION 0)
Setting this value to 0
will not impose any limit, you can set this number to the size of your dataset if you know it up front.