【问题标题】:Count first occurence with column value ordered by another column计算由另一列排序的列值的第一次出现
【发布时间】:2016-05-06 14:37:55
【问题描述】:

我有一个 assigns 表,其中包含以下列:

id - int
id_lead - int
id_source - int
date_assigned - int (this represents a unix timestamp)

现在,假设我在此表中有以下数据:

id id_lead id_source date_assigned
1  20      5         1462544612
2  20      6         1462544624
3  22      6         1462544615
4  22      5         1462544626
5  22      7         1462544632
6  25      6         1462544614
7  25      8         1462544621

现在,假设我想计算 id_source 为 6 的行数,并且是每个潜在客户的第一个条目(按 date_assigned asc 排序)。

所以在这种情况下,计数 = 2,因为有 2 个潜在客户(id_lead 22 和 25),其第一个 id_source 为 6。

我将如何编写此查询以使其速度快并且可以作为子查询选择正常工作?我在想这样的事情是行不通的:

select count(*) from `assigns` where `id_source`=6 order by `date_assigned` asc limit 1

我不知道如何以最佳方式编写此查询。任何帮助将不胜感激。

【问题讨论】:

  • 查看我的更新,我认为简单的查询对你来说已经足够了

标签: mysql select count


【解决方案1】:

伪代码:

select rows 
with a.id_source = 6
but only if
    there do not exist any row
        with same id_lead
        and smaller date_assigned

将其翻译成 SQL

select *                                     -- select rows 
from assigns a
where a.id_source = 6                        -- with a.id_source = 6
  and not exists (                           -- but only if there do not exist any row
    select 1
    from assigns a1
    where a1.id_lead = a.id_lead             -- with same id_lead
      and a1.date_assigned < a.date_assigned -- and smaller date_assigned
  )

现在将select * 替换为select count(*),您将得到结果。

http://sqlfiddle.com/#!9/3dc0f5/7

更新:

NOT-EXIST 查询可以重写为排除 LEFT JOIN 查询:

select count(*)
from assigns a
left join assigns a1
    on  a1.id_lead = a.id_lead
    and a1.date_assigned < a.date_assigned
where a.id_source = 6
  and a1.id_lead is null

如果您想获取id_source 的所有值的计数,以下查询可能是最快的:

select a.id_source, count(1)
from (
    select a1.id_lead, min(a1.date_assigned) date_assigned
    from assigns a1
    group by a1.id_lead
) a1
join assigns a
    on  a.id_lead = a1.id_lead
    and a.date_assigned = a1.date_assigned
group by a.id_source

您仍然可以将group by a.id_source 替换为where a.id_source = 6

查询需要assigns(id_source)assigns(id_lead, date_assigned) 上的索引。

【讨论】:

  • 我写了一个类似的查询,但问题是我希望它在子查询中。从优化的角度来看,子查询中的子查询是不可能的。不过感谢您的帮助。
  • @kjdion84,如果你写过类似的查询,你应该在你的问题中提到并解释为什么它不是一个解决方案。但是,返回常量值(在本例中为“2”)的(派生)子查询应该不是问题。如果您的子查询将被关联(类似:where a.id_source = outer.id_source),那么最好在 JOIN 中使用我的最后一个查询而不是子查询。
【解决方案2】:

对此的简单查询是

在这里查看http://sqlfiddle.com/#!9/8666e0/7

select count(*) from 
(select * from assigns group by id_lead )t 
where t.id_source=6

【讨论】:

    猜你喜欢
    • 2020-12-20
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 2022-06-16
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多