有没有替代rank()over(分区...排序方式)

Is there an alternative to rank() over(partition by...order by)

提问人:Spam 提问时间:10/18/2023 最后编辑:philipxySpam 更新时间:10/20/2023 访问量:53

问:

我正在尝试更改rank()(分区...订购方式...)在子查询中,由于 rank() 导致查询性能变慢,因此 THE GROUP BY 和 min/max 中。这是因为在子查询对每一行进行分区后,它会对其进行排名。我只想要每个申请人的第一个工作日期,而不必经过排名和分区。

我已经注释掉了查询的原始部分,以显示我尝试过的内容。

  1. 我已经包括了用子查询选择替换 where 子句。join applicants_cte apps on apps.person_key = apps.person_key
  2. 按所有选定的字段分组。我想将 替换为 a,这样我就不必对每一行数据进行分区。partition by ap.person_id group by ap.person_id
  3. 我包括替换 .min(ap.working_date)order by ap.work_date asc

这些步骤给了我预期的计数输出(1,500,000),但是一旦我删除了,我得到了一个非常大的计数输出(34,000,000)。select * (from (select rank() over (partition by ap.person_id order by ap.working_date asc)

with applicants_cte as 
    (select person_key
    from applicants.people
    where date is between '01-01-2022' and '01-01-2023'
    group by person_key
    )
    ,
list_of_applicants as 
    -- Removed subquery and rank()
    /*
    (select *
    from (select rank() over (partition by ap.person_id order by 
        ap.working_date asc) list,
    */
    (select min(ap.working_date),
        ap.person_id
        date(applicants.start_date) as start_date,
        a.first_name,
        a.last_name,
        b.email_address
    from applicants.people ap
    join information a on a.person_key = ap_id_key
    join contact_information b on b.person_info_id = ap.id_key
    -- replaced where statement with join 
    join applicants_cte apps on apps.person_key = apps.person_key
    where date(applicants.start_date) IS NOT NULL
    /*
    where date(applicants.start_date) IS NOT NULL
    and ap.person_id in (select applicant_id 
        from applicants_cte)) c
    where c.list = 1
    */
    group by ap.person_id,
        start_date,
        a.first_name,
        a.last_name,
        b.email_address
    ) 
select count(*) from list_of_applicants
SQL 子查询 amazon-redshift query-optimization common-table-expression

评论

1赞 Stu 10/18/2023
您是否考虑过提供索引来支持 Rank 窗口函数的排序?
0赞 Isolated 10/18/2023
是否给了你正确的值?我还没有真正完成该查询,但我认为您可以使用 CTE 来获取它们的开始日期。select count(distinct person_id)
2赞 O. Jones 10/18/2023
欢迎使用 Stack Overflow。恕我直言,很难从您的问题中推断出您的输出要求或表格结构。当我个人陷入像你的查询所显示的那样咆哮时(我经常这样做),我会退后一步,从第一原则进行推理:我有这些数据,我想要那个答案。
0赞 philipxy 10/20/2023
调试问题需要一个最小的可重现示例--剪切、粘贴和可运行的代码,包括初始化;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。对于 SQL,包括 DDL 和表格初始化代码。对于包括 EXPLAIN 结果和统计信息的 SQL 性能。
0赞 philipxy 10/20/2023
Stack Overflow 用户需要付出多少研究努力? 最小可重复示例 提出一个好的 SQL 问题的技巧 询问查询性能问题 如何优化数据库中的查询 - 基础知识 您最常见的 SQL 优化是什么? 数据库联接何时以及为何如此昂贵?

答:

0赞 Spam 10/20/2023 #1

我需要为我的第一个 CTE 添加一个 DISTINCT,我将第二个 CTE 拆分为两个子查询。applicants_ctelist_of_applicants