Условный ROW_NUMBER (), чтобы пропустить нули, все еще считая их - PullRequest
0 голосов
/ 19 ноября 2018

Я пытаюсь добавить столбец ROW_NUMBER к набору данных, который соответствует порядку [Снятие, затем Комиссия; Снятие с комиссии затем] в зависимости от того, является ли столбец NETWORKCD нулевым. Тем не менее, моя формула row_number все еще считает Nulls, даже если она не отображает числа, например так:

+--------+-------------+------------+-----------+-------------+
| Acctid | Transaction |  PostDate  | NetworkCd | PeriodCount |
+--------+-------------+------------+-----------+-------------+
|  12345 | Withdrawal  | 10/4/2018  | FRGN      |           1 |
|  12345 | Fee         | 10/4/2018  |           |             |
|  12345 | Withdrawal  | 10/11/2018 | FRGN      |           3 |
|  12345 | Fee         | 10/11/2018 |           |             |
|  12345 | Withdrawal  | 10/22/2018 | FRGN      |           5 |
|  12345 | Fee         | 10/22/2018 |           |             |
+--------+-------------+------------+-----------+-------------+

Я использую следующую формулу для PeriodCount

(case when networkcd is not null 
      then row_number() over (partition by acctid order by postdate) 
 end) PeriodCount

Я ожидал, что PeriodCount будет считать [1,2,3] вместо [1,3,5], вот так:

+--------+-------------+------------+-----------+-------------+
| Acctid | Transaction |  PostDate  | NetworkCd | PeriodCount |
+--------+-------------+------------+-----------+-------------+
|  12345 | Withdrawal  | 10/4/2018  | FRGN      |           1 |
|  12345 | Fee         | 10/4/2018  |           |             |
|  12345 | Withdrawal  | 10/11/2018 | FRGN      |           2 |
|  12345 | Fee         | 10/11/2018 |           |             |
|  12345 | Withdrawal  | 10/22/2018 | FRGN      |           3 |
|  12345 | Fee         | 10/22/2018 |           |             |
+--------+-------------+------------+-----------+-------------+

Чего мне не хватает?

Ответы [ 3 ]

0 голосов
/ 19 ноября 2018

Он по-прежнему показывает значение 1-й, 3-й и 5-й строк - поэтому количество строк при каждой встрече с этими строками является правильным. Это номер строки во всем наборе результатов, а не в ненулевых значениях. Ваше выражение case решает, показывать ли значение, не влияя на то, как оно найдено.

Вы можете получить желаемый результат, используя dense_rank() вместо

with your_table (Acctid, Transaction, PostDate, NetworkCd) as (
          select 12345, 'Withdrawal', to_date('10/4/2018', 'MM/DD/YYYY'), 'FRGN' from dual
union all select 12345, 'Fee', to_date('10/4/2018', 'MM/DD/YYYY'), null from dual
union all select 12345, 'Withdrawal', to_date('10/11/2018', 'MM/DD/YYYY'), 'FRGN' from dual
union all select 12345, 'Fee', to_date('10/11/2018', 'MM/DD/YYYY'), null from dual
union all select 12345, 'Withdrawal', to_date('10/22/2018', 'MM/DD/YYYY'), 'FRGN' from dual
union all select 12345, 'Fee', to_date('10/22/2018', 'MM/DD/YYYY'), null from dual
)
select Acctid, Transaction, PostDate, NetworkCd,
(case when networkcd is not null then dense_rank() over (partition by acctid order by postdate) end) as periodcount
from your_table;

    ACCTID TRANSACTIO POSTDATE   NETW PERIODCOUNT
---------- ---------- ---------- ---- -----------
     12345 Withdrawal 2018-10-04 FRGN           1
     12345 Fee        2018-10-04                 
     12345 Withdrawal 2018-10-11 FRGN           2
     12345 Fee        2018-10-11                 
     12345 Withdrawal 2018-10-22 FRGN           3
     12345 Fee        2018-10-22                 

... поскольку это подавляет пробелы в сгенерированных значениях. Из документов :

DENSE_RANK вычисляет ранг строки в упорядоченной группе строк и возвращает ранг как NUMBER. Ранги - это последовательные целые числа, начинающиеся с 1. ...

0 голосов
/ 19 ноября 2018

Похоже, что вместо NULL это пустая строка. SQL будет рассматривать это по-другому в коде.

Попытка:

case when networkcd = '' then row_number()....
0 голосов
/ 19 ноября 2018

ROW_NUMBER() функция не работает, как вы ожидали, но вы можете сделать вместо этого:

select t.*,
       (select count(*)
        from table t1
        where t1.acctid = t.acctid and t1.PostDate <= t.PostDate and
              t1.networkcd is not null 
       ) as PeriodCount
from table t;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...