Hi I have a table of data I want to output the dense_rank of the names starting from the first group of names according to sorted dates order. e.g.
DROP TABLE MyTable
SELECT * INTO MyTable FROM (
VALUES ('2015-12-23', 'ccc'),('2015-12-21', 'aaa'),
('2015-12-20', 'bbb'),('2015-12-22', 'aaa')
) t (date, name)
SELECT DENSE_RANK() OVER (ORDER BY name) rank, * FROM MyTable ORDER BY date
For the query above I got
rank date name
2 2015-12-20 bbb
1 2015-12-21 aaa
1 2015-12-22 aaa
3 2015-12-23 ccc
You can see the dates are sorted (good), ranks are assigned to names in group (good), but the ranks do not start from the first group of name, e.g. I want
rank date name
1 2015-12-20 bbb
2 2015-12-21 aaa
2 2015-12-22 aaa
3 2015-12-23 ccc
How would you correct the query? If there are multiple working answers, the simplest/shortest one will be picked as the answer. Thanks.
Thanks @lad2025 and @GiorgosBetsos for clarifying my question. Sorting is straightly according to dates and dates are unique in my case. Names can repeat and appear non-consecutively. So with ('2015-12-24', 'aaa')
, the output is
rank date name
1 2015-12-20 bbb
2 2015-12-21 aaa
2 2015-12-22 aaa
3 2015-12-23 ccc
4 2015-12-24 aaa
DENSE_RANK computes the rank of a row in an ordered group of rows and returns the rank as a NUMBER . The ranks are consecutive integers beginning with 1. The largest rank value is the number of unique values returned by the query.
rank and dense_rank are similar to row_number , but when there are ties, they will give the same value to the tied values. rank will keep the ranking, so the numbering may go 1, 2, 2, 4 etc, whereas dense_rank will never give any gaps.
The Oracle/PLSQL DENSE_RANK function returns the rank of a row in a group of rows. It is very similar to the RANK function. However, the RANK function can cause non-consecutive rankings if the tested values are the same. Whereas, the DENSE_RANK function will always result in consecutive rankings.
The syntax of the DENSE_RANK() function is as follows: DENSE_RANK() OVER ( [PARTITION BY partition_expression, ... ] ORDER BY sort_expression [ASC | DESC], ... ) The DENSE_RANK( ) function is applied to the rows of each partition defined by the PARTITION BY clause, in a specified order, defined by ORDER BY clause.
You can use:
SELECT DENSE_RANK() OVER (ORDER BY minGrpDate),
[date], name
FROM (
SELECT MIN([date]) OVER (PARTITION BY grp) AS minGrpDate,
[date], name
FROM (
SELECT [date], name,
ROW_NUMBER() OVER (ORDER BY [date])
-
ROW_NUMBER() OVER (PARTITION BY name ORDER BY [date]) AS grp
FROM mytable) AS t ) AS s
ORDER BY Date
Explanation:
grp
field identifies islands of consecutive records having the same name
. minGrpDate
, which is calculated using grp
, is the minimum date of each island.minGrpDate
we can now apply DENSE_RANK()
to get required rank.Note1: The above query handles discontinuities in name
field, i.e. the case of non-consecutive fields having the same name.
Note2: The query does not handle the case of different name
values sharing the same date
value.
Demo here
First rank distinct names ordered by date and then join on the table:
;WITH cte AS(SELECT name, ROW_NUMBER() OVER(ORDER BY MIN(date)) rn
FROM dbo.MyTable
GROUP BY name)
SELECT c.rn, m.date, m.name
FROM cte c
JOIN dbo.MyTable m ON m.name = c.name
ORDER BY m.date
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With