AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 281995
Accepted
Nir
Nir
Asked: 2020-12-23 08:06:59 +0800 CST2020-12-23 08:06:59 +0800 CST 2020-12-23 08:06:59 +0800 CST

查找具有重复版本的组

  • 772

我想在表中查找具有重复组版本的所有组。一个组可以有多个组版本。每个组版本可以有多个成员。组“版本”由grpid和定义changeDate。如果一个组版本中的所有成员(和)与同一组中的另一个组版本匹配userid,则该组认为重复。pcthobby

https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=84eb81a1a71dcee9ad3d0bd91f56120a

表groups:

ID grpid 改变日期 用户身份 百分比 爱好 团体版*
1 1 2020-01-01 1 1 1 1
2 1 2020-01-02 1 1 2 2
3 1 2020-01-03 1 1 1 3
4 2 2020-01-01 1 0.5 1 4
5 2 2020-01-01 2 0.5 2 4
6 2 2020-01-02 1 0.5 1 5
7 2 2020-01-02 2 0.5 3 5
8 3 2020-01-01 1 0.5 1 6
9 3 2020-01-01 2 0.5 2 6
10 3 2020-01-02 1 0.4 1 7
11 3 2020-01-02 2 0.6 2 7
12 4 2020-01-01 1 0.6 1 8
13 4 2020-01-01 2 0.4 2 8
14 4 2020-01-02 1 0.6 1 9
15 4 2020-01-02 2 0.4 2 9
16 5 2020-01-01 1 0.2 2 10
17 5 2020-01-01 2 0.5 1 10
18 5 2020-01-01 3 0.3 2 10
19 6 2020-01-01 1 0.3 2 11
20 6 2020-01-01 2 0.5 1 11
21 6 2020-01-01 3 0.2 2 11
22 6 2020-02-01 1 0.2 2 12
23 6 2020-02-01 2 0.5 1 12
24 6 2020-02-01 3 0.3 2 12
25 6 2020-03-01 1 0.3 2 13
26 6 2020-03-01 2 0.3 1 13
27 6 2020-03-01 3 0.4 2 13
28 7 2020-01-01 1 0.3 2 14
29 7 2020-01-01 2 0.5 1 14
30 7 2020-01-01 3 0.2 2 14
31 7 2020-02-01 1 0.3 2 15
32 7 2020-02-01 2 0.5 1 15
33 7 2020-02-01 3 0.2 2 15
34 7 2020-03-01 1 0.3 2 16
35 7 2020-03-01 2 0.3 1 16
36 7 2020-03-01 3 0.4 2 16
37 8 2020-02-01 1 0.3 1 17
38 8 2020-03-01 1 0.3 1 18
39 8 2020-03-01 3 0.4 2 18

*唯一组版本号仅用于可视化。

结果应该是:

grpid
1
4
7

解释:

  • grpid 1 - 有 3 个组版本(1 个成员) - 1 和 3 个重复,因为 userid、pct 和 hobby 相等
  • grpid 2 - 有 2 个组版本(2 个成员) - 不重复,因为 5 和 7 之间的爱好不相等
  • grpid 3 - 有 2 个组版本(2 个成员) - 不重复,因为 pct 在所有成员中都不同
  • grpid 4 - 有 2 个组版本(2 个成员) - 所有成员都是重复的,因为 userid、pct 和 userid 相等
  • grpid 5 - 只有一组 3 名成员 - 不重复
  • grpid 6 - 有 3 个组版本(3 个成员) - 不重复 - 版本之间组中每个成员的 pct 更改
  • grpid 7 - 有 3 个组版本(3 个成员) - 重复,因为 userid、pct 和 userid 在 28-30 和 31-33 之间相等
  • grpid 8 - 有 2 个组版本,一个有一个成员,一个有 2 个成员 - 不重复,因为该组中有另一个成员

我正在使用 MySQL 5.7。

mysql select
  • 3 3 个回答
  • 119 Views

3 个回答

  • Voted
  1. Best Answer
    Vérace
    2020-12-24T03:42:34+08:002020-12-24T03:42:34+08:00

    希望这应该提供一个答案:

    这实现了“通用”关系划分:

    SELECT DISTINCT grpid
    FROM groups AS g
    GROUP BY grpid, changeDate
    HAVING NOT EXISTS
        ( SELECT 1
          FROM groups AS gi
          WHERE gi.grpid = g.grpid
            AND gi.changeDate = g.changeDate
            AND NOT EXISTS
                ( SELECT 1 
                   FROM groups AS gk
                   WHERE gk.grpid = gi.grpid
                     AND gk.changeDate <> gi.changeDate
                     AND gk.userid = gi.userid
                     AND gk.pct = gi.pct
                     AND gk.hobby = gi.hobby
                )
        ) ;
    

    结果:

    grid
       1
       4
       7
    

    这实现了精确的关系除法,这导致了更复杂的代码。您的情况下,分组/版本由两列确定,(grpid, changeDate)这使它看起来更加复杂。

    在dbffdle.uk中测试

    查询一:

    SELECT DISTINCT g1.grpid
    FROM 
      ( SELECT grpid, changeDate
        FROM groups AS g
        GROUP BY grpid, changeDate
      ) AS g1
      JOIN
      ( SELECT grpid, changeDate
        FROM groups AS g
        GROUP BY grpid, changeDate
      ) AS g2
      ON  g1.grpid = g2.grpid
      AND g1.changeDate < g2.changeDate
    WHERE NOT EXISTS
        ( SELECT 1
          FROM groups AS gi
          WHERE gi.grpid = g1.grpid
            AND gi.changeDate = g1.changeDate
            AND NOT EXISTS
                ( SELECT 1 
                   FROM groups AS gk
                   WHERE gk.grpid = g2.grpid
                     AND gk.changeDate = g2.changeDate
                     AND gk.userid = gi.userid
                     AND gk.pct = gi.pct
                     AND gk.hobby = gi.hobby
                )
        )
       AND NOT EXISTS
        ( SELECT 1
          FROM groups AS gi
          WHERE gi.grpid = g2.grpid
            AND gi.changeDate = g2.changeDate
            AND NOT EXISTS
                ( SELECT 1 
                   FROM groups AS gk
                   WHERE gk.grpid = g1.grpid
                     AND gk.changeDate = g1.changeDate
                     AND gk.userid = gi.userid
                     AND gk.pct = gi.pct
                     AND gk.hobby = gi.hobby
                )
        )
     ;
    

    使用 MySQLGROUP_CONCAT函数的查询 2:

    SELECT DISTINCT grpid
    FROM
      ( SELECT grpid, changeDate, 
               GROUP_CONCAT( CONCAT_WS('-', userid, hobby, pct)
                             ORDER BY userid, hobby, pct
                             SEPARATOR '  '
                           ) AS groupdata 
        FROM groups AS gr
        GROUP BY grpid, changeDate
      ) AS g
    GROUP BY grpid, groupdata
    HAVING COUNT(*) > 1 ;
    
    • 3
  2. nbk
    2020-12-23T08:58:47+08:002020-12-23T08:58:47+08:00

    您可以为此使用内部联接

    仅供参考 mysql 8 由于不喜欢组作为表名,并且必须放在反引号中

    并且行 id = 2 和 id = 4 也是“相同的,并且属于您的规则

    create table groups ( id int,  grpid int , changeDate date,  userid int,  pct double ,  hobby int );
    
    insert into groups(id , grpid , changeDate  ,userid  ,pct  ,hobby ) values
    (1  , 1      ,'2020-01-01', 1   ,    1   , 1  ),
    (2  , 1      ,'2020-01-02', 1   ,    1   , 2  ),
    (3  , 1      ,'2020-01-03', 1   ,    1   , 1  ),
    (4  , 2      ,'2020-01-01', 1   ,    0.5 , 1  ),
    (5  , 2      ,'2020-01-01', 1   ,    0.5 , 2  ),
    (6  , 2      ,'2020-01-02', 1   ,    0.5 , 1  ),
    (7  , 2      ,'2020-01-02', 1   ,    0.5 , 3  ),
    (8  , 3      ,'2020-01-01', 1   ,    0.5 , 1  ),
    (9  , 3      ,'2020-01-01', 1   ,    0.5 , 2  ),
    (10 , 3      ,'2020-01-02', 1   ,    0.4 , 1  ),
    (11 , 3      ,'2020-01-02', 1   ,    0.6 , 2  ),
    (12 , 4      ,'2020-01-01', 1   ,    0.6 , 1  ),
    (13 , 4      ,'2020-01-01', 1   ,    0.4 , 2  ),
    (14 , 4      ,'2020-01-02', 1   ,    0.6 , 1  ),
    (15 , 4      ,'2020-01-02', 1   ,    0.4 , 2  );
    
    SELECT DISTINCT g1.grpid 
    FROM `groups` g1 INNER JOIN  `groups` g2
    ON g1.grpid = g2.grpid 
    AND g1.hobby = g2.hobby 
    AND g1.pct = g2.pct 
    AND g1.userid = g2.userid
    WHERE g1.id <> g2.id
    
    | grpid |
    | ----: |
    | 1 |
    | 2 |
    | 4 |
    

    db<>在这里摆弄

    • 2
  3. J.D.
    2020-12-23T08:25:40+08:002020-12-23T08:25:40+08:00
    SELECT DISTINCT grpid
    FROM TableWithGroups
    GROUP BY grpid, userid, pct, hobby
    HAVING COUNT(*) > 1
    

    这使用GROUP BY 和 HAVING子句分别将您指定的字段上的值分组以将重复项压缩为一行并过滤每个分组中压缩的行数大于 1(换句话说,存在重复项) .

    • 0

相关问题

  • 是否有任何 MySQL 基准测试工具?[关闭]

  • 我在哪里可以找到mysql慢日志?

  • 如何优化大型数据库的 mysqldump?

  • 什么时候是使用 MariaDB 而不是 MySQL 的合适时机,为什么?

  • 组如何跟踪数据库架构更改?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve