Есть ли функция, которая может вернуть отрицательный рейтинг для значений.оракул - PullRequest
0 голосов
/ 21 января 2019

У меня есть сценарий, в котором я должен ранжировать отрицательный для значений ниже порогового предела в SQL.Может ли кто-нибудь помочь мне в этом?

Name    Target  Rank
John    2500    -2
Hopkins 4000    -1
Paul    5000    0
Gracia  5200    1

Выше приведен пример таблицы целей.Мне нужно назначить ряды, как показано.Для людей, имеющих значение 5000, должно быть присвоено «0».Для ресурса ниже 5000 должно быть отрицательное значение ранжирования (-1, -2, -3 ...) Для ресурса выше 5000 должно быть положительное значение ранга (1,2,3) ранжирования.- введите описание изображения здесь

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Это достойная транскрипция вашего требования.

У вас есть три различных случая target, поэтому вы устанавливаете case с тремя расчетами ветвей RANK.

Вы можете использовать обычную RANK совокупную аналитическую функцию, но технически вы должны PARTITION BY в своих трех случаях.

select NAME, TARGET,
case when target = 5000 then 0
     when target > 5000 then RANK()
        over (partition by case when target > 5000 then 1 when target < 5000 then -1 else 0 end 
        order by target) 
     when target < 5000 then - RANK() 
        over (partition by case when target > 5000 then 1 when target < 5000 then -1 else 0 end 
        order by - target)
end as rank
from tab;

NAME        TARGET       RANK
------- ---------- ----------
John          2500         -2
Hopkins       4000         -1
Paul          5000          0
Gracia        5200          1
0 голосов
/ 21 января 2019

Используйте комбинацию аналитических функций ROW_NUMBER() и COUNT():

Установка Oracle :

CREATE TABLE table_name ( Name, Target ) As
SELECT 'John',    2500 FROM DUAL UNION ALL
SELECT 'Hopkins', 4000 FROM DUAL UNION ALL
SELECT 'Paul',    5000 FROM DUAL UNION ALL
SELECT 'Gracia',  5200 FROM DUAL;

Запрос :

SELECT t.*,
       ROW_NUMBER() OVER ( ORDER BY target ASC )
         - COUNT( CASE WHEN target < 5000 THEN 1 END ) OVER ()
         - 1 AS rnk
FROM   table_name t;

выход

NAME    | TARGET | RNK
:------ | -----: | --:
John    |   2500 |  -2
Hopkins |   4000 |  -1
Paul    |   5000 |   0
Gracia  |   5200 |   1

дБ <> скрипка здесь


Обновление

Установка Oracle :

CREATE TABLE table_name ( Name, Target ) As
SELECT 'John',    2500 FROM DUAL UNION ALL
SELECT 'Hopkins', 4000 FROM DUAL UNION ALL
SELECT 'Bob',     5000 FROM DUAL UNION ALL
SELECT 'Smith',   5000 FROM DUAL UNION ALL
SELECT 'Paul',    5100 FROM DUAL UNION ALL
SELECT 'Janet',   5100 FROM DUAL UNION ALL
SELECT 'Gracia',  5200 FROM DUAL;

Запрос 1 : если вы хотите получить уникальный ранг для каждой строки и не хотите ранг 0, если нет значения 5000:

SELECT t.*,
       ROW_NUMBER() OVER ( ORDER BY target ASC, name ASC )
         - COUNT( CASE WHEN target < 5000 THEN 1 END ) OVER ()
         - CASE WHEN target > 5000 AND COUNT( CASE WHEN target = 5000 THEN 1 END ) OVER () = 0 THEN 0 ELSE 1 END AS rnk
FROM   table_name t;

выход

NAME    | TARGET | RNK
:------ | -----: | --:
John    |   2500 |  -2
Hopkins |   4000 |  -1
Bob     |   5000 |   0
Smith   |   5000 |   1
Janet   |   5100 |   2
Paul    |   5100 |   3
Gracia  |   5200 |   4

Запрос 2 : если вы хотите, чтобы строки с одной и той же целью имели одинаковый ранг и имели цели только с 5000, ранг 0:

SELECT name,
       target,
       DENSE_RANK() OVER ( ORDER BY target ASC )
         - COUNT( CASE WHEN target < 5000 AND rn = 1 THEN 1 END ) OVER ()
         - CASE WHEN target > 5000 AND COUNT( CASE WHEN target = 5000 AND rn = 1 THEN 1 END ) OVER () = 0 THEN 0 ELSE 1 END AS rnk
FROM   (
  SELECT t.*,
         ROW_NUMBER() OVER ( PARTITION BY target ORDER BY name ) AS rn
  FROM   table_name t
);

выход

NAME    | TARGET | RNK
:------ | -----: | --:
John    |   2500 |  -2
Hopkins |   4000 |  -1
Bob     |   5000 |   0
Smith   |   5000 |   0
Janet   |   5100 |   1
Paul    |   5100 |   1
Gracia  |   5200 |   2

дБ <> скрипка здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...