mysql查询可以高效地返回不包含重复信息的组合行

3okqufwl  于 2021-08-01  发布在  Java
关注(0)|答案(2)|浏览(377)

所以这很可能是件简单的事情,但我正在努力找出一个有效的方法。我看了很多其他的问答,我搞乱了不同的,分组,子查询等。
我试着把这个例子超级简化(在本例中,没有db规范化)下面是一个sql小提琴:
http://sqlfiddle.com/#!9/948be7c/1号

CREATE TABLE IF NOT EXISTS `orders` (
  `id` int NOT NULL,
  `name` varchar(90) NULL,
  `email` varchar(200) NULL,
  `phone` varchar(200) NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;

INSERT INTO `orders` (`id`, `name`, `email`, `phone`) VALUES
  ('1', 'Bob', 'bob@email.com', NULL),
  ('2', 'Bobby', 'bob@email.com', '1115551111'),
  ('3', 'Robert', 'robert@email.com', '1115551111'),
  ('4', 'Fred', 'fred@email.com', '1115552222'),
  ('5', 'Freddy', 'fred@email.com', '1115553333')

如果我只运行一个简单的select,我会得到:

但我想“消除重复”任何结果有相同的电子邮件地址或有相同的电话号码-因为他们将是相同的人,即使他们有多个身份证,即使他们的名字拼写不同。然后合并这些结果(一个“不同的”电子邮件地址和一个“不同的”电话号码,以及一个姓名和一个身份证号码)
因此,对于上述情况,我会得出这样的结论:

有什么建议吗?

piok6c0g

piok6c0g1#

我认为,通过使用相关子查询进行过滤,您可以做您想做的事情:

select o.*
from orders o
where o.id = (
    select o1.id
    from orders o1
    where o1.email = o.email or o1.phone = o.phone
    order by o1.phone is not null desc, o1.email is not null desc, id
    limit 1
)

这只保留了具有相同属性的行中的一行 phone 或者 email ,同时优先考虑 phone 以及 email 不是 null . 选择最低的就可以打破束缚 id .
对于示例数据,返回:

id  name    email           phone
2   Bobby   bob@email.com   1115551111
4   Fred    fred@email.com  1115552222
ojsjcaue

ojsjcaue2#

有许多不同的方式可以解释您的需求。
一种方法是将其重新构造为约束:仅当其中一个为真时才返回记录:
它具有非空的电子邮件和电话,并且不存在具有相同电子邮件和电话且id较低的记录
邮件不为空,电话不为空,同一封邮件和电话不为空,同一封邮件和电话不为空,id较低,不存在记录
电话不为空,邮件不为空,同一电话和邮件不存在记录,同一电话和邮件不为空,id较低不存在记录
这很容易转化为几个连接,不需要groupby或distinct。

相关问题