英文:
DENSE_RANK() with two order by columns with the same value
问题
我正在尝试使用 DENSE_RANK()
函数对支付列表进行排名,并按两个数据点 [PAYROLL DATE]
和 [PROCESS DATE]
对结果进行排序。然而,当 ORDER BY
中的两列相同时,DENSE_RANK()
会将它们视为相同的排名。
以下是我的查询的一部分示例。
DENSE_RANK() OVER (PARTITION BY [Plan ID], [EE ID], [Loan Number]
ORDER BY ISNULL([PAYROLL DATE], [PROCESS DATE]) ASC)
[Plan ID] | [EE ID] | [Loan Num] | [PAYROLL DATE] | [PROCESS DATE] | (期望) 排名 | (实际) 排名 |
---|---|---|---|---|---|---|
ABC123 | 1234 | 1 | 11/26/2021 | NULL | 1 | 1 |
ABC123 | 1234 | 1 | 12/23/2021 | NULL | 2 | 2 |
ABC123 | 1234 | 1 | 02/18/2022 | NULL | 3 | 3 |
ABC123 | 1234 | 1 | 02/18/2022 | NULL | 3 | 3 |
ABC123 | 1234 | 1 | NULL | 02/18/2022 | 4 | 3 |
在上面的示例中,我希望排名从1到4。但我看到所有日期为2/18的三个记录都被合并在一起(都排名为3)。是否有其他函数我应该使用以获得我想要的结果?
提前谢谢!
我尝试了不同的 DENSE_RANK()
变体,但没有成功。我还尝试了 RANK()
和 ROW_NUMBER()
,但在结果中没有真正给我我想要的内容。
英文:
I'm trying to rank a list of payments using DENSE_RANK()
function and ordering the results by two data points [PAYROLL DATE]
and [PROCESS DATE]
. However, when the two columns in the ORDER BY
are the same, the DENSE_RANK()
is treating them as the same rank.
Here is a snippet of what my query says.
DENSE_RANK() OVER (PARTITION BY [Plan ID], [EE ID], [Loan Number]
ORDER BY ISNULL([PAYROLL DATE], [PROCESS DATE]) ASC)
[Plan ID] | [EE ID] | [Loan Num] | [PAYROLL DATE] | [PROCESS DATE] | (Desired) RANK | (Actual) RANK |
---|---|---|---|---|---|---|
ABC123 | 1234 | 1 | 11/26/2021 | NULL | 1 | 1 |
ABC123 | 1234 | 1 | 12/23/2021 | NULL | 2 | 2 |
ABC123 | 1234 | 1 | 02/18/2022 | NULL | 3 | 3 |
ABC123 | 1234 | 1 | 02/18/2022 | NULL | 3 | 3 |
ABC123 | 1234 | 1 | NULL | 02/18/2022 | 4 | 3 |
In the above example, I want the ranking to go from 1 to 4. What I am seeing is that all three records with dates of 2/18 are being lump together (all ranked as 3). Is there another function I should use to get the results I want?
Thank you in advance!
I've tried different variations of DENSE_RANK()
to no avail. I've also tried RANK()
and ROW_NUMBER()
and nothing is truly giving me what I'm looking for in the results.
答案1
得分: 1
使用在您的ORDER BY子句中使用case表达式
的一种方法来管理这些空值。
create table table1 (
plan_id varchar(10),
ee_id integer,
loan_number integer,
payroll_date date,
process_date date);
insert into table1 values
('aaa', 1234, 1, '2021-11-26', null),
('aaa', 1234, 1, '2021-12-23', null),
('aaa', 1234, 1, '2022-02-18', null),
('aaa', 1234, 1, '2022-02-18', null),
('aaa', 1234, 1, null, '2022-02-18');
select plan_id, ee_id, loan_number, payroll_date, process_date,
DENSE_RANK() OVER
(PARTITION BY plan_id,ee_id,loan_number ORDER BY case when payroll_date is null then 1 else 0 end, payroll_date,process_date asc) as r
from table1
plan_id | ee_id | loan_number | payroll_date | process_date | r |
---|---|---|---|---|---|
aaa | 1234 | 1 | 2021-11-26 | null | 1 |
aaa | 1234 | 1 | 2021-12-23 | null | 2 |
aaa | 1234 | 1 | 2022-02-18 | null | 3 |
aaa | 1234 | 1 | 2022-02-18 | null | 3 |
aaa | 1234 | 1 | null | 2022-02-18 | 4 |
编辑
或者,继续使用您的ISNULL表达式,但使用远未来的日期代替process_date。然而,如果在相同的分区列中有多个null payroll_date行但process_dates不同,这个备选答案可能不会提供期望的结果。如果null只出现一次,这个方法可以正常工作。因此,我可能会坚持使用case表达式的答案。
select plan_id, ee_id, loan_number, payroll_date, process_date,
dense_RANK() OVER
(PARTITION BY plan_id,ee_id,loan_number ORDER BY isnull(payroll_date,'9999-12-31') asc) as r
from table1
英文:
One way to using a case expression
in your order by clause to manage those null values.
create table table1 (
plan_id varchar(10),
ee_id integer,
loan_number integer,
payroll_date date,
process_date date);
insert into table1 values
('aaa', 1234, 1, '2021-11-26', null),
('aaa', 1234, 1, '2021-12-23', null),
('aaa', 1234, 1, '2022-02-18', null),
('aaa', 1234, 1, '2022-02-18', null),
('aaa', 1234, 1, null, '2022-02-18');
select plan_id, ee_id, loan_number, payroll_date, process_date,
DENSE_RANK() OVER
(PARTITION BY plan_id,ee_id,loan_number ORDER BY case when payroll_date is null then 1 else 0 end, payroll_date,process_date asc) as r
from table1
plan_id | ee_id | loan_number | payroll_date | process_date | r |
---|---|---|---|---|---|
aaa | 1234 | 1 | 2021-11-26 | null | 1 |
aaa | 1234 | 1 | 2021-12-23 | null | 2 |
aaa | 1234 | 1 | 2022-02-18 | null | 3 |
aaa | 1234 | 1 | 2022-02-18 | null | 3 |
aaa | 1234 | 1 | null | 2022-02-18 | 4 |
EDIT
Or, continue using your ISNULL expression but use a far-fetched future date instead of the process_date. HOWEVER, this alternate answer may not provide desired results if you have more than one null payroll_date row with the same partitioned_by columns, but different process_dates. This works fine if null appears just once. Therefore, I would probably stick with the case expression answer.
select plan_id, ee_id, loan_number, payroll_date, process_date,
dense_RANK() OVER
(PARTITION BY plan_id,ee_id,loan_number ORDER BY isnull(payroll_date,'9999-12-31') asc) as r
from table1
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论