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