【问题标题】:LIMIT based on COUNT of DISTINCT `foreign_key` so farLIMIT 基于迄今为止 DISTINCT `foreign_key` 的 COUNT
【发布时间】:2019-07-20 10:19:56
【问题描述】:

我有 2 个表“站点”和“卡车”(由 distance 订购)的联合。记录集如下所示:

我需要获取所有行,直到从第 1 行开始达到特定 (n) 个唯一的 company_id。

所以,如果我得到如下信息:

然后我可以做一个简单的查询,例如:

SELECT * FROM union_recordset where distinct_company_id_count_so_far < (3 + 1);
-- where n = 3

并获得所需的结果:

【问题讨论】:

  • 您已使用不同的数据库标记了该问题。您应该只使用您真正使用的数据库进行标记。
  • 对于这类问题,最好在sqlfiddle.com建表和样本数据,这样你和回答问题的人就可以轻松测试解决方案。

标签: sql postgresql window-functions


【解决方案1】:

如果您的数据库支持 count(distinct) 作为窗口函数:

select ur.*,
       count(distinct company_id) over (order by distance) as cnt
from union_recordset ur
order by distance;

如果没有,你可以计算第一次出现:

select ur.*,
       sum(case when seqnum = 1 then 1 else 0 end) over (order by distance) as cnt
from (select ur.*,
             row_number() over (partition by company_id order by distance) as seqnum
      from union_recordset ur
     ) ur
order by distance;

在 Postgres 中,sum() 可以简化为:

       sum( (seqnum = 1)::int ) over (order by distance) as cnt

然后要获得前三个公司的数字,您需要:

select ur.*
from (select ur.*,
             sum( (seqnum = 1)::int ) over (order by distance) as cnt
      from (select ur.*,
                   row_number() over (partition by company_id order by distance) as seqnum
            from union_recordset ur
           ) ur
     ) ur
where cnt <= 3
order by distance;

【讨论】:

  • 子查询select ur.*, row_number() over (partition by company_id order by distance) as seqnum from union_recordset ur 没有返回distance 的有序列表。它仅按company_id 排序,这进一步导致父查询出现问题。感谢您的帮助!
  • @RAJ 。 . .我不明白。子查询中的顺序无关紧要。如果您希望结果按特定顺序排列,请使用order by 进行外部查询。
  • @RAJ 。 . .你似乎有很多很多公司都有相同的距离。它们都被同时计算在内。
  • 我的要求是它们应该只计算一次。意思是,每个 company_id 应该只从按距离排序的记录集中计算一次。
  • @RAJ 。 . .您的数据有数千家公司,距离完全相同。它们都只计算一次。这些在您的数据中看起来像是测试公司,因此您可能只想将它们过滤掉。
【解决方案2】:

您可以选择您的公司,然后加入它自己以获取其他数据:

select ur.* from union_recordset ur join
  (select distinct company_id from union_recordset order by distance limit 3) ur_d
  on (ur.company_id = ur_d.company_id)

注意:PostgreSQL 8.1 后支持Limit 命令。

【讨论】:

    猜你喜欢
    • 2017-08-14
    • 1970-01-01
    • 2014-11-16
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多