Sql 将有限选择和总计数组合在一起?

Sql 将有限选择和总计数组合在一起?,sql,postgresql,amazon-redshift,Sql,Postgresql,Amazon Redshift,我有一个名为profile的表,其中包含用户信息。我需要在此表上执行筛选查询并获取: 与此查询匹配的行数 仅显示前5000个匹配行的数据 我正在寻找一个最佳的方法来做到这一点。显然,至少需要一次扫描才能进行计数,但理想情况下,DB可以在进行计数时获取最匹配的数据 下面的查询给出了正确的结果,但它看起来有点粗糙。我想知道是否可以做得更好 WITH total AS ( SELECT COUNT(*) AS total FROM profile WHERE projec

我有一个名为
profile
的表,其中包含用户信息。我需要在此表上执行筛选查询并获取:

  • 与此查询匹配的行数
  • 仅显示前5000个匹配行的数据
  • 我正在寻找一个最佳的方法来做到这一点。显然,至少需要一次扫描才能进行计数,但理想情况下,DB可以在进行计数时获取最匹配的数据

    下面的查询给出了正确的结果,但它看起来有点粗糙。我想知道是否可以做得更好

    WITH total AS (
         SELECT COUNT(*) AS total FROM profile 
             WHERE project_id = 1 and some_prop = 100)
    SELECT total.total, full_name, other_prop 
        FROM profile
        INNER JOIN total ON 1 = 1
        WHERE project_id = 1 and some_prop = 100
        ORDER BY full_name ASC
        LIMIT 5000
    

    是否有更有效的方法执行此操作?

    您正在扫描同一个表两次以应用筛选器。使用下面的选项,您只扫描表格一次,并在过滤后的表格上应用“过滤器”和“总计”和“列表”

    with s as (
        select *
        from profile 
        where project_id = 1 and some_prop = 100
    ), t as (
        select count(*) as total from s
    )
    select total, full_name, other_prop 
    from s cross join t
    order by full_name asc
    limit 5000
    
    窗口函数版本

    select
        count(*) over() as total,
        full_name,
        other_prop 
    from profile
    where project_id = 1 and some_prop = 100
    order by full_name asc
    limit 5000
    

    考虑到您所做的工作,我不认为它有什么特别的问题,但是您可以将“1=1上的内部连接总计”更改为“交叉连接总计”,这更有意义,尽管我怀疑它是否会表现得更好。基本上是此的副本:。但不确定红移,这是过时和现代功能的奇怪组合。你的窗口方法也是红移中最快的(到目前为止)。谢谢,我没有想过这样做。此查询的执行计划实际上与我之前的查询相同。它可能已经达到了预期的效果。@AndySavage测试window函数版本window方法在查询计划中看起来更好。伟大的