Sql 条件行_NUMBER()跳过仍在计数的空值

Sql 条件行_NUMBER()跳过仍在计数的空值,sql,plsql,oracle11g,Sql,Plsql,Oracle11g,我正试图根据列NETWORKCD是否为空,按照[Retraction then Fee;Retraction then Fee]的顺序向数据集中添加一个行号列。但是,我的行数公式仍然在计算空值,即使它没有显示数字,如下所示: +--------+-------------+------------+-----------+-------------+ | Acctid | Transaction | PostDate | NetworkCd | PeriodCount | +--------

我正试图根据列NETWORKCD是否为空,按照[Retraction then Fee;Retraction then Fee]的顺序向数据集中添加一个行号列。但是,我的行数公式仍然在计算空值,即使它没有显示数字,如下所示:

+--------+-------------+------------+-----------+-------------+
| 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 |           |             |
+--------+-------------+------------+-----------+-------------+
+--------+-------------+------------+-----------+-------------+
| 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 |           |             |
+--------+-------------+------------+-----------+-------------+
我使用以下公式计算周期计数

我希望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      |           3 |
|  12345 | Fee         | 10/11/2018 |           |             |
|  12345 | Withdrawal  | 10/22/2018 | FRGN      |           5 |
|  12345 | Fee         | 10/22/2018 |           |             |
+--------+-------------+------------+-----------+-------------+
+--------+-------------+------------+-----------+-------------+
| 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 |           |             |
+--------+-------------+------------+-----------+-------------+
我遗漏了什么?

行数函数无法按预期工作,但您可以改为:

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;
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;

它仍然在第1行、第3行和第5行显示一个值,因此遇到这些行时的行数是正确的。它是整个结果集中的行号,而不是not null值中的行号。您的case表达式决定是否显示该值,而不影响如何找到该值

你可以用稠密的秩来得到你想要的结果

。。。因为这会抑制生成值中的间隙:

稠密_秩计算有序行组中某行的秩,并以数字形式返回秩。列组是从1…开始的连续整数


它仍然在第1行、第3行和第5行显示一个值,因此遇到这些行时的行数是正确的。它是整个结果集中的行号,而不是not null值中的行号。您的case表达式决定是否显示该值,而不影响如何找到该值

你可以用稠密的秩来得到你想要的结果

。。。因为这会抑制生成值中的间隙:

稠密_秩计算有序行组中某行的秩,并以数字形式返回秩。列组是从1…开始的连续整数


它看起来不是空的,而是一个空字符串。SQL将在代码中以不同的方式考虑这一点

尝试:


它看起来不是空的,而是一个空字符串。SQL将在代码中以不同的方式考虑这一点

尝试:


尝试将分区按acctid更改为分区按acctid,NetworkCd不为空

尝试将分区按acctid更改为分区按acctid,NetworkCd不为空

Alex Poole的答案有效,但这取决于空行与要计数的非空行具有相同的后发日期这一事实。如果将日期更改为彼此不同,则会看到密集_列失败:

with your_table (Acctid, Transaction, PostDate, NetworkCd) as (
              select 12345, 'Withdrawal', to_date('10/1/2018', 'MM/DD/YYYY'), 'FRGN'
    union all select 12345, 'Fee', to_date('10/2/2018', 'MM/DD/YYYY'), null
    union all select 12345, 'Withdrawal', to_date('10/3/2018', 'MM/DD/YYYY'), 'FRGN'
    union all select 12345, 'Fee', to_date('10/4/2018', 'MM/DD/YYYY'), null
    union all select 12345, 'Withdrawal', to_date('10/5/2018', 'MM/DD/YYYY'), 'FRGN'
    union all select 12345, 'Fee', to_date('10/6/2018', 'MM/DD/YYYY'), null
    )

select
    Acctid,
    Transaction,
    PostDate,
    NetworkCd,
    case when networkcd is not null then dense_rank() over (partition by Acctid order by PostDate) end as PeriodCount,
    dense_rank() over (partition by Acctid order by PostDate) as DenseRank
from your_table
order by Acctid, PostDate, Transaction
;
屈服

acctid  transaction  postdate    networkcd  periodcount  denserank
------  -----------  ----------  ---------  -----------  ---------
12345   Withdrawal   2018-10-01  FRGN       1            1
12345   Fee          2018-10-02                          2
12345   Withdrawal   2018-10-03  FRGN       3            3
12345   Fee          2018-10-04                          4
12345   Withdrawal   2018-10-05  FRGN       5            5
12345   Fee          2018-10-06                          6
acctid  transaction  postdate    networkcd  periodcount  rownumber
------  -----------  ----------  ---------  -----------  ---------
12345   Withdrawal   2018-10-01  FRGN       1            1
12345   Fee          2018-10-02                          1
12345   Withdrawal   2018-10-03  FRGN       2            2
12345   Fee          2018-10-04                          2
12345   Withdrawal   2018-10-05  FRGN       3            3
12345   Fee          2018-10-06                          3
在右边,显示没有空条件的稠密_秩的结果,因此它适用于您的情况,但总体上不可靠

Kevin Siemons的答案效果更好:它分别计算空行和非空行,您可以简单地隐藏对空行的计数:

with your_table (Acctid, Transaction, PostDate, NetworkCd) as (
              select 12345, 'Withdrawal', to_date('10/1/2018', 'MM/DD/YYYY'), 'FRGN'
    union all select 12345, 'Fee', to_date('10/2/2018', 'MM/DD/YYYY'), null
    union all select 12345, 'Withdrawal', to_date('10/3/2018', 'MM/DD/YYYY'), 'FRGN'
    union all select 12345, 'Fee', to_date('10/4/2018', 'MM/DD/YYYY'), null
    union all select 12345, 'Withdrawal', to_date('10/5/2018', 'MM/DD/YYYY'), 'FRGN'
    union all select 12345, 'Fee', to_date('10/6/2018', 'MM/DD/YYYY'), null
    )

select
    Acctid,
    Transaction,
    PostDate,
    NetworkCd,
    case when networkcd is not null then row_number() over (partition by Acctid, NetworkCd is not null order by PostDate) end as PeriodCount,
    row_number() over (partition by Acctid, NetworkCd is not null order by PostDate) as RowNumber
from your_table
order by Acctid, PostDate, Transaction
;
屈服

acctid  transaction  postdate    networkcd  periodcount  denserank
------  -----------  ----------  ---------  -----------  ---------
12345   Withdrawal   2018-10-01  FRGN       1            1
12345   Fee          2018-10-02                          2
12345   Withdrawal   2018-10-03  FRGN       3            3
12345   Fee          2018-10-04                          4
12345   Withdrawal   2018-10-05  FRGN       5            5
12345   Fee          2018-10-06                          6
acctid  transaction  postdate    networkcd  periodcount  rownumber
------  -----------  ----------  ---------  -----------  ---------
12345   Withdrawal   2018-10-01  FRGN       1            1
12345   Fee          2018-10-02                          1
12345   Withdrawal   2018-10-03  FRGN       2            2
12345   Fee          2018-10-04                          2
12345   Withdrawal   2018-10-05  FRGN       3            3
12345   Fee          2018-10-06                          3

我建议使用case,当networkcd不为null时,则按Acctid分区上的行数,networkcd不为null,按PostDate end作为PeriodCount排序。

Alex Poole的答案有效,但这取决于空行的PostDate与要计数的非空行的PostDate相同这一事实。如果将日期更改为彼此不同,则会看到密集_列失败:

with your_table (Acctid, Transaction, PostDate, NetworkCd) as (
              select 12345, 'Withdrawal', to_date('10/1/2018', 'MM/DD/YYYY'), 'FRGN'
    union all select 12345, 'Fee', to_date('10/2/2018', 'MM/DD/YYYY'), null
    union all select 12345, 'Withdrawal', to_date('10/3/2018', 'MM/DD/YYYY'), 'FRGN'
    union all select 12345, 'Fee', to_date('10/4/2018', 'MM/DD/YYYY'), null
    union all select 12345, 'Withdrawal', to_date('10/5/2018', 'MM/DD/YYYY'), 'FRGN'
    union all select 12345, 'Fee', to_date('10/6/2018', 'MM/DD/YYYY'), null
    )

select
    Acctid,
    Transaction,
    PostDate,
    NetworkCd,
    case when networkcd is not null then dense_rank() over (partition by Acctid order by PostDate) end as PeriodCount,
    dense_rank() over (partition by Acctid order by PostDate) as DenseRank
from your_table
order by Acctid, PostDate, Transaction
;
屈服

acctid  transaction  postdate    networkcd  periodcount  denserank
------  -----------  ----------  ---------  -----------  ---------
12345   Withdrawal   2018-10-01  FRGN       1            1
12345   Fee          2018-10-02                          2
12345   Withdrawal   2018-10-03  FRGN       3            3
12345   Fee          2018-10-04                          4
12345   Withdrawal   2018-10-05  FRGN       5            5
12345   Fee          2018-10-06                          6
acctid  transaction  postdate    networkcd  periodcount  rownumber
------  -----------  ----------  ---------  -----------  ---------
12345   Withdrawal   2018-10-01  FRGN       1            1
12345   Fee          2018-10-02                          1
12345   Withdrawal   2018-10-03  FRGN       2            2
12345   Fee          2018-10-04                          2
12345   Withdrawal   2018-10-05  FRGN       3            3
12345   Fee          2018-10-06                          3
在右边,显示没有空条件的稠密_秩的结果,因此它适用于您的情况,但总体上不可靠

Kevin Siemons的答案效果更好:它分别计算空行和非空行,您可以简单地隐藏对空行的计数:

with your_table (Acctid, Transaction, PostDate, NetworkCd) as (
              select 12345, 'Withdrawal', to_date('10/1/2018', 'MM/DD/YYYY'), 'FRGN'
    union all select 12345, 'Fee', to_date('10/2/2018', 'MM/DD/YYYY'), null
    union all select 12345, 'Withdrawal', to_date('10/3/2018', 'MM/DD/YYYY'), 'FRGN'
    union all select 12345, 'Fee', to_date('10/4/2018', 'MM/DD/YYYY'), null
    union all select 12345, 'Withdrawal', to_date('10/5/2018', 'MM/DD/YYYY'), 'FRGN'
    union all select 12345, 'Fee', to_date('10/6/2018', 'MM/DD/YYYY'), null
    )

select
    Acctid,
    Transaction,
    PostDate,
    NetworkCd,
    case when networkcd is not null then row_number() over (partition by Acctid, NetworkCd is not null order by PostDate) end as PeriodCount,
    row_number() over (partition by Acctid, NetworkCd is not null order by PostDate) as RowNumber
from your_table
order by Acctid, PostDate, Transaction
;
屈服

acctid  transaction  postdate    networkcd  periodcount  denserank
------  -----------  ----------  ---------  -----------  ---------
12345   Withdrawal   2018-10-01  FRGN       1            1
12345   Fee          2018-10-02                          2
12345   Withdrawal   2018-10-03  FRGN       3            3
12345   Fee          2018-10-04                          4
12345   Withdrawal   2018-10-05  FRGN       5            5
12345   Fee          2018-10-06                          6
acctid  transaction  postdate    networkcd  periodcount  rownumber
------  -----------  ----------  ---------  -----------  ---------
12345   Withdrawal   2018-10-01  FRGN       1            1
12345   Fee          2018-10-02                          1
12345   Withdrawal   2018-10-03  FRGN       2            2
12345   Fee          2018-10-04                          2
12345   Withdrawal   2018-10-05  FRGN       3            3
12345   Fee          2018-10-06                          3

我建议使用case when networkcd not null,然后使用Acctid分区上的行号,networkcd not null order by PostDate end as PeriodCount。

在本例中,行号就是行号,无论您在case语句中选择显示还是替换为null,不会改变它是哪个行号。@Andrew这是我的第一个想法,但networkcd的case语句不是空的吗?恐怕不是,Alex发布的Dense\u Rank是前进的方向,它的工作方式有细微的区别行号正是在这种情况下的行号,无论您选择在case语句中显示它还是用null替换它,都不会改变它是哪一行。@Andrew这是我的第一个想法,但是networkcd的case语句不是null吗?恐怕不是,Alex发布的稠密等级是前进的方向,在它的工作方式上有细微的差别,非常感谢。我会花些时间来研究一下,非常好用,谢谢。我会花些时间调查一下密密麻麻的队伍。。将任何内容与=进行比较的结果与=null相同,后者为“未知”。。将任何内容与=进行比较的结果与=null相同,后者为“未知”。