从表 mysql 中获取重复的条目

Posted

技术标签:

【中文标题】从表 mysql 中获取重复的条目【英文标题】:Get the duplicate entries from table mysql 【发布时间】:2018-04-26 02:13:03 【问题描述】:

我的表结构如下所示。数据库是 MariaDB。

+-----------+----------+--------------+-----------------+
| id_object |   name   | value_double | value_timestamp |
+-----------+----------+--------------+-----------------+
|     1     | price    | 1589         |  null           |
|     1     | payment  | 1590         |  null           |
|     1     | date     | null         |  2012-04-17     |
|     2     | price    | 1589         |  null           |
|     2     | payment  | 1590         |  null           |
|     2     | date     | null         |  2012-04-17     |
|     3     | price    | 1589         |  null           |
|     3     | payment  | 1590         |  null           |
|     3     | date     | null         |  2012-09-25     |
|    ...    | ...      | ...          |  ..             |
+-----------+----------+--------------+-----------------+

1) 我需要通过三个条目获取重复项:价格、付款和日期; 例如:id_object=2 的记录是重复的,因为价格、付款和日期与 id_object=1 的记录的值相同。 id_object = 3 的记录不是重复的,因为日期不同 (2012-09-25 != 2012-04-17) 2)我应该删除除了一份副本之外的重复项。

我想进行三个选择操作并在 id_object 上加入每个选择。我可以通过一个条目(价格 | 付款 | 日期)获得副本。我在连接时遇到了问题

SELECT `id_object`,`name`,P.`value_double` | P.`value_timestamp`
FROM record P
INNER JOIN(
SELECT value_double | value_timestamp
FROM record
WHERE name = required_entry
GROUP BY value_double | value_timestamp
HAVING COUNT(id_object) > 1
)temp ON P.value_double = temp.value_double | P.value_timestamp = temp.value_timestamp
WHERE name = required_entry

有人可以帮助并展示纯粹(更好)的解决方案吗?

【问题讨论】:

使用 EAV 模型时,我更喜欢根据数据类型将属性分离到单独的表中,这样您就不会最终得到所有这些空值。 你能给出预期的结果吗? 分组依据无效。不会在较新的 mysql 版本上执行(除非在兼容模式下),可能会在较旧的 MySQL 版本上返回不可预测的结果。一般的 GROUP BY 规则说:如果指定了 GROUP BY 子句,则 SELECT 列表中的每个列引用必须要么标识一个分组列,要么是一个集合函数的参数! 【参考方案1】:

我将group_concat() 将这些值放在一起并以这种方式进行测试:

 select t.*
 from t join
      (select min(id_object) id_object
       from (select id_object,
                    group_concat(name, ':', coalesce(value_double, ''), ':', coalesce(value_timestamp, '') order by name) pairs
             from t
             where name in ('price', 'payment', 'date')
             group by id_object
            ) tt
        group by pairs
     ) tt
     on t.id_object = tt.id_object; 

实际删除不是每组相关值的最小值id

delete t
    from t left join
         (select min(id) as id
          from (select id, group_concat(name, ':', coalesce(value_double, ''), ':', coalesce(value_timestamp, '' order by name) as pairs,
                from t
                where name in ('price', 'payment', 'date')
                group by id
               ) tt
          group by pairs
         ) tt
         on t.id = tt.id
    where tt.id is null;

【讨论】:

谢谢!很好的解决方案 @Miracle633 赞美很甜蜜,但点赞更甜蜜 ;-)【参考方案2】:

虽然效率低于某些替代方案,但我发现沿着这些思路的方法更易于阅读...

SELECT MIN(id_object) id_object
     , price
     , payment
     , date 
  FROM 
     ( SELECT id_object
            , MAX(CASE WHEN name = 'price'   THEN value_double END) price
            , MAX(CASE WHEN name = 'payment' THEN value_double END) payment
            , MAX(CASE WHEN name = 'date'    THEN value_timestamp END) date
         FROM eav
        GROUP 
           BY id_object
     ) x
 GROUP  
    BY price
     , payment
     , date;

【讨论】:

以上是关于从表 mysql 中获取重复的条目的主要内容,如果未能解决你的问题,请参考以下文章

从表中获取全部内容

mySql获取重复条目的最后记录[重复]

mySql获取重复条目的最后记录[重复]

MySQL 查询从表中检索数据和第二个查询以提取其他结果,没有重复

从表中获取某一列的十大列表

从表中检索的条目是不是重复? PHP