使用两个相同值的ORDER BY列的DENSE_RANK()

huangapple go评论70阅读模式
英文:

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

fiddle

编辑

或者,继续使用您的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

fiddle

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

huangapple
  • 本文由 发表于 2023年7月13日 00:35:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76672750.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定