Плотная_ранговая функция SQL

Это вопрос функции sql плотно_rank. Я исследовал Интернет, пытаясь найти ответ. Я пробовал несколько версий, но ничего не работает. У меня такая проблема: 13 июля кто-то изменил программу. Начиная с 14 июля, программа теперь стирает поле зарплаты. Я должен найти самую последнюю запись, которая = 0, а затем вторую самую последнюю запись, где она> 0. Это один из кодов, которые я пробовал:

(SELECT contract_nbr, 
        business_unit, 
        ymdeff, 
        ymdend, 
        ymdtrans, 
        void, 
        salary, 
        Dense_rank() 
          OVER ( 
            partition BY contract_nbr 
            ORDER BY ymdend, salary DESC) 
 FROM   (SELECT DISTINCT contract_nbr, 
                         business_unit, 
                         ymdeff, 
                         ymdend, 
                         ymdtrans, 
                         void, 
                         salary 
         FROM   contract_span 
         WHERE  business_unit = 'KA' 
                AND ymdtrans > 20130714 
                AND contract_nbr = 'XXXX')) 

Это результаты. Они выглядят хорошо, за исключением того, что мне нужны только две нижние строки. Есть ли способ просто получить последние 2 строки? YMDEND не всегда 99991231, поэтому я не могу использовать это поле.

CONTRACT_NBR    BUSINESS_UNIT   YMDEFF  YMDEND  YMDTRANS    VOID    SALARY
XXXX                  KA      20130101  20130531    20130725    V   129300
XXXX                  KA      20130101  20130531    20130725        0
XXXX                  KA      20130601  99991231    20130725    V   129300
XXXX                  KA      20130601  99991231    20130725        0

person Donna Greene    schedule 12.08.2013    source источник


Ответы (1)


Я не думаю, что ты хочешь dense_rank() вообще. Вместо этого разделите каждый контракт по тому, равна ли зарплата 0. Затем используйте row_number() для перечисления значений и логики, чтобы выбрать, какие из них вы хотите:

from (SELECT contract_nbr, business_unit, ymdeff, ymdend, ymdtrans, void, salary,
             row_number() over (partition by contract_nbr,
                                             (case when salary = 0 then '0' else '+' end)
                                order by ymdend desc
                               ) as SalarySeqNum
      . . .
     ) t
where (salary = 0 and salarySeqNum = 1) or
      (salary > 0 and salarySeqNum = 2)
person Gordon Linoff    schedule 12.08.2013