【问题标题】:Mysql: find number of rows which have same value one-after-otherMysql:逐个查找具有相同值的行数
【发布时间】:2016-03-04 17:35:18
【问题描述】:

假设我有桌子

id|val
1 |1
2 |1
3 |2
4 |5
5 |2
6 |2
7 |2

如何获得这样的表格:

2 | 1 |2
3 | 2 |1
4 | 5 |1
7 | 2 |3

即表格,其中第三列是第二列中相似值的数量。

当然我可以使用 php 或 perl 代码来做到这一点,但我记得只使用 sql 变量是可行的。

【问题讨论】:

  • 我不知道用什么逻辑来获取第二个表。
  • @GordonLinoff,第一列说明取值的最后位置。第二列表示要计算的次数,第三列表示出现的次数。
  • 看。通过第二列,计算值的数量。假设您以 id=2 计数。在 id=2 处,您在第二列 1 中。如果您进入下一步 (id=3) 值而不是 2,则将一行 (1,2) 放在 2 为计数的位置。现在数 2,得到一个 2,所以放 (2,1)。下一个是 (5,1),之后你有 2 个中的 3 个,所以 (2,3)。现在更清楚了吗?
  • @arheops,您需要查询还是其他解决方案都可以?
  • 我需要查询。其他解决方案(如程序或外部语言)我可以自己做。但我很确定可以查询(我自己在大学实验室做过)。

标签: mysql sql


【解决方案1】:

哦,我想我明白了。您关心相邻的值序列。第一列是最大id,第二列是值,第三列是长度。

是的,您可以使用变量来做到这一点:

select max(id), val, count(*)
from (select t.*,
             (@grp := if(@v = val, @grp,
                         if(@v := val, @grp + 1, @grp + 1)
                        )
             ) as grp
      from yourtable t cross join
           (select @v := -1, @grp := -1) params
      order by id
     ) t
group by grp, val
order by max(id);

【讨论】:

  • 你测试过这个吗?它给了我同一张桌子+第三个字段,总是1。
  • 希望您不介意,但我编辑了您的解决方案以使其正常工作并提供了一个小提琴演示。这是 imo 的最佳解决方案。
  • 是的,这个接缝没问题。复杂度是 O(n^2) 还是 O(n)?
  • 基于测试它是 O(n) 并且在核心 2 2700(默认 mysql 配置)上 10000 条记录需要 0.072 秒
  • @sgeddes 。 . .谢谢你。我在想什么(反问)。
【解决方案2】:

一个纯粹主义者可能对此有意见 - 但我是一个纯粹主义者,我不...

SELECT MAX(id) max_id
     , val -- or MAX(val) if you like
     , COUNT(*) total
  FROM 
     ( SELECT id
            , val
            , CASE WHEN @prev <> val THEN @i:=@i+1 ELSE @i:=@i END i
            , @prev := val prev 
         FROM yourtable
            , (SELECT @prev:=null, @i:=1) vars 
        ORDER 
           BY id
     ) a
 GROUP 
    BY i;

http://www.sqlfiddle.com/#!9/32d395/16

哦,看起来很像另一个答案

【讨论】:

  • 是的,除了你没有显式交叉连接(但仍然有它)之外它是一样的。
  • 这不是纯粹主义者的问题。您正在使用变量并在 不同的 表达式中分配它们。不幸的是,MySQL 不保证表达式的求值顺序,并且在某些情况下按词法顺序处理它们(这不仅仅是理论上的问题,尽管文档确实有警告) .因此,一个人分配变量,然后在另一个表达式中使用它们,风险自负。
  • 是的。在这种情况下,不会出现不一致。
猜你喜欢
  • 1970-01-01
  • 2010-12-19
  • 1970-01-01
  • 2018-11-15
  • 2018-12-25
  • 2011-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多