草庐IT

mysql - 按 id 对行进行分组,然后将不同的组相互比较

coder 2023-10-25 原文

我有一张表,里面有很多seq_id的数据。每个 seq_id 在不同的行上有很多命中 (hit_name_id)。我想做的是将 seqs 分组,如果它们的命中率相似(即共享约 70-80% 的命中率),例如下表中的序列 1,2 和 4 实际上非常相似,因此它们很可能是一样。我希望能够为所有相似的命中分配一个组 ID,以便我以后可以只提取唯一的序列。

我创建这个查询是为了证明每个 seq_id 可以有很多可能共享也可能不共享的命中:

mysql> SELECT seq_id,GROUP_CONCAT(hit_name_id ORDER BY hit_name_id), count(hit_name_id) FROM polished_data
    -> GROUP BY seq_id;
+--------+------------------------------------------------+--------------------+
| seq_id | GROUP_CONCAT(hit_name_id ORDER BY hit_name_id) | count(hit_name_id) |
+--------+------------------------------------------------+--------------------+
|      1 | 4,5,6,9,10,14,19,20,21                         |                  9 |
|      2 | 4,6,9,10,14,18,19,20,21                        |                  9 |
|      3 | 6,12,13,14,18,20                               |                  6 |
|      4 | 4,7,8,11,14,18,19,20,21                        |                  9 |
|      5 | 1,2,3,15,16,17,32                              |                  7 |
+--------+------------------------------------------------+--------------------+

我不确定我是否可以在 MySQL 中完成此操作,或者我是否需要在我的链接程序中编写此步骤。

最佳答案

这将计算相同的命中数。

SELECT seq_id, COUNT(*) AS same
FROM polished_data
WHERE 
    hit_name_id IN (SELECT hit_name_id FROM polished WHERE seq_id = ###) 
    AND and seq_id != ### 
GROUP BY seq_id

然后您可以扩展它并计算有多少不同(它出现在其中一个而不是两个),然后将它们连接在一起。

SELECT *, (same/(same+diff)) AS similarity   
FROM
(
    SELECT 
        s.seq_id, 
        s.same,
        ((t.total-s.same)+(ct.total-s.same)) AS diff 

    FROM 

        (SELECT seq_id, COUNT(*) as total FROM polished_data
         GROUP BY seq_id) AS t  

    LEFT JOIN

        (SELECT seq_id, COUNT(*) AS same
         FROM polished_data
         WHERE 
             hit_name_id IN 
                 (SELECT hit_name_id FROM polished_data 
                  WHERE seq_id = ###) 
         GROUP BY seq_id) AS s

    ON t.seq_id = s.seq_id

    JOIN

        (SELECT COUNT(*) as total FROM polished_data
         WHERE seq_id = ###) AS ct  

) as result   

使用随机数据你会得到这样的结果(使用 ### 替换为 1 进行测试)。

+--------+------+------+------------+
| seq_id | same | diff | similarity |
+--------+------+------+------------+
|      1 |   22 |    0 |     1.0000 |
|      2 |    4 |   45 |     0.0816 |
|      3 |    5 |   57 |     0.0806 |
|      4 |    8 |   34 |     0.1905 |
|      5 |    9 |   47 |     0.1607 |
|      6 |    3 |   36 |     0.0769 |
|      7 |    7 |   45 |     0.1346 |
|      8 |    3 |   48 |     0.0588 |
|      9 |    9 |   46 |     0.1636 |
|     10 |    4 |   48 |     0.0769 |
+--------+------+------+------------+

将上述 SQL 中的 ### 更改为您要比较的 seq_id。

关于mysql - 按 id 对行进行分组,然后将不同的组相互比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6873595/

有关mysql - 按 id 对行进行分组,然后将不同的组相互比较的更多相关文章

  1. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  2. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  3. ruby - 按值降序排列散列,然后按升序键入 ruby - 2

    我有这样的哈希trial_hash={"key1"=>1000,"key2"=>34,"key3"=>500,"key4"=>500,"key5"=>500,"key6"=>500}我按值降序排列:my_hash=trial_hash.sort_by{|k,v|v}.reverse我现在是这样理解的:[["key1",1000],["key4",500],["key5",500],["key6",500],["key3",500],["key2",34]]但我希望当值相同时按键的升序排序。我该怎么做?例如:上面的散列将以这种方式排序:[["key1",1000],["key3",500

  4. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  5. ruby - 在 Ruby 中创建按公共(public)键值分组的新哈希 - 2

    假设我有一个在Ruby中看起来像这样的哈希:{:ie0=>"Hi",:ex0=>"Hey",:eg0=>"Howdy",:ie1=>"Hello",:ex1=>"Greetings",:eg1=>"Goodday"}有什么好的方法可以将它变成如下内容:{"0"=>{"ie"=>"Hi","ex"=>"Hey","eg"=>"Howdy"},"1"=>{"ie"=>"Hello","ex"=>"Greetings","eg"=>"Goodday"}} 最佳答案 您要求一个好的方法来做到这一点,所以答案是:一种您或同事可以在六个月后理解

  6. java - 为什么 ruby​​ modulo 与 java/other lang 不同? - 2

    我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.

  7. ruby-on-rails - 在 RSpec 中,如何以任意顺序期望具有不同参数的多条消息? - 2

    RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)

  8. ruby - Rails -- :id attribute? 所需的数据库索引 - 2

    因此,当我遵循MichaelHartl的RubyonRails教程时,我注意到在用户表中,我们为:email属性添加了一个唯一索引,以提高find的效率方法,因此它不会逐行搜索。到目前为止,我们一直在根据情况使用find_by_email和find_by_id进行搜索。然而,我们从未为:id属性设置索引。:id是否自动索引,因为它在默认情况下是唯一的并且本质上是顺序的?或者情况并非如此,我应该为:id搜索添加索引吗? 最佳答案 大多数数据库(包括sqlite,这是RoR中的默认数据库)会自动索引主键,对于RailsMigration

  9. ruby-on-rails - 如何用不同的用户运行nginx主进程 - 2

    A/ctohttp://wiki.nginx.org/CoreModule#usermaster进程曾经以root用户运行,是否可以以不同的用户运行nginxmaster进程? 最佳答案 只需以非root身份运行init脚本(即/etc/init.d/nginxstart),就可以用不同的用户运行nginxmaster进程。如果这真的是你想要做的,你将需要确保日志和pid目录(通常是/var/log/nginx&/var/run/nginx.pid)对该用户是可写的,并且您所有的listen调用都是针对大于1024的端口(因为绑定(

  10. ruby - 是否有用于复杂比较的漂亮语法? - 2

    方法应返回-1,0或1分别表示“小于”、“等于”和“大于”。对于某些类型的可排序对象,通常将排序顺序基于多个属性。以下是可行的,但我认为它看起来很笨拙:classLeagueStatsattr_accessor:points,:goal_diffdefinitializepts,gd@points=pts@goal_diff=gdenddefothercompare_pts=pointsother.pointsreturncompare_ptsunlesscompare_pts==0goal_diffother.goal_diffendend尝试一下:[LeagueStats.new(

随机推荐