• Getting values <1 for the highest PERCENT_RANK() is quite normal. All that has to happen is for the value ordered last by the ORDER BY to be repeated in the data, so that there are ties at the top.

    The data type of the value being ordered doesn't come into play (in the following example the expression being ordered is an int).

    The following code illustrates this:

    DECLARE @table TABLE (SomeInt int)

    INSERT INTO @table

    SELECT TOP 10000 RN

    FROM (SELECT ROW_NUMBER () OVER (ORDER BY ac1.object_id) RN

    FROM sys.all_columns ac1

    CROSS JOIN sys.all_columns ac2) a

    --This shows us a max value of 1, as expected.

    SELECT TOP 1

    PR=PERCENT_RANK() OVER (ORDER BY SomeInt asc )

    FROM @table

    ORDER BY PR DESC

    --Now make sure there's a tie between two rows at the top

    INSERT INTO @table

    SELECT 10000

    --This will yield 0.9999 as the max PERCENT_RANK

    SELECT TOP 1

    PR=PERCENT_RANK() OVER (ORDER BY SomeInt asc )

    FROM @table

    ORDER BY PR DESC

    DELETE FROM @table

    INSERT INTO @table

    VALUES (1),(2),(2)

    --With a tie at the top of a very small partition, the max value gets quite low.

    --Here it's 0.5.

    --In fact, if there is only one value for the ORDER BY expression in the partition,

    --then the highest PERCENT_RANK will be 0

    SELECT TOP 1

    PR=PERCENT_RANK() OVER (ORDER BY SomeInt asc )

    FROM @table

    ORDER BY PR DESC

    I hope this helps clear up why this might be happening. You probably just have ties for the value sorted last by your ORDER BY expression.

    You could consider using CUME_DIST () instead, which will return a 1 for the value sorted last regardless of ties, but it's a bit different calculation than PERCENT_RANK (), so you'll want to make sure it's appropriate for your purposes.

    Cheers!