【问题标题】:Select rows with duplicate values that may be in different columns选择可能在不同列中具有重复值的行
【发布时间】:2021-07-14 18:52:17
【问题描述】:

我有一张商家表,每个商家最多可以有 3 个电话号码。我想查找任何重复的电话号码,但由于电话号码位于不同的列中,我认为我无法使经典的 GROUP BY 查询工作。

样本数据:

ID Business_Name phone_main phone_mobile phone_tollfree
1 John's Donuts 555-551-5555 555-551-5556 null
2 John's Bakery 555-551-5557 555-551-5555 null
3 SuperBake! 555-300-1005 null 555-551-5555
4 Grocery Fred 555-223-5511 555-334-5555 null

在这种情况下,我想将记录 1、2 和 3 标识为相同的。只需将电话号码 555-551-5555 识别为具有重复项的号码就可以了,因为我可以进行子查询,或者调用程序可以使用电话号码并发送一个新查询,以获取所有包含 555-551-5555 的记录3 个电话列。

如果重要的话,这在 MariaDB 上。

编辑,(添加我当前的尝试,因为似乎有人真的想要它):

这是我现在拥有的:

SELECT ID, phone_main, phone_mobile, phone_tollfree
(
    SELECT COUNT(*) FROM businesses b
    WHERE (
        phone IS NOT NULL AND (b.phone_mobile=phone OR b.tollfree=phone )
    )

    OR (
        phone_mobile IS NOT NULL AND (b.phone=phone_mobile OR b.phone_tollfree=phone_mobile)
    )

    OR (
        phone_tollfree IS NOT NULL AND (b.phone=phone_tollfree OR b.phone_mobile=phone_tollfree)
    ) 
) cnt


from business HAVING cnt > 1

这个问题:

  1. 它似乎正在返回我表中的每一行。
  2. 它不会在单个列中找到重复项。

【问题讨论】:

  • 继续。尝试一下。
  • 像什么?我可以轻松地group by 任何单列。或者我可以做一堆加入 phone_mainphone_mobile 等的连接,或者我可以尝试某种子查询,但我在这里寻找策略,不一定是确切的代码。
  • 任你挑选。
  • 也许我应该在帖子中更清楚一些,但我整个上午都在努力想办法做到这一点。我已经运行了group by 查询,但它们没有帮助,因为有不止一列。我想不出一种方法来加入有用的东西,而且我当前的子查询没有返回有意义的数据。我发帖是因为我没有想法。我在寻求帮助,被告知“继续。试试看”。没有帮助。

标签: mysql sql duplicates mariadb grouping


【解决方案1】:

如何将所有电话列合并为一个然后计算重复出现的次数?

我没有运行代码,但它可能会给你一个方向......:

SELECT phone, COUNT(phone)
FROM (
SELECT phone_main as phone FROM SampleData
UNION ALL

(SELECT phone_mobile as phone FROM SampleData
ORDER BY City;

UNION ALL
SELECT phone_tollfree as phone FROM SampleData
ORDER BY City; and )
)
GROUP BY phone

【讨论】:

  • 这也可以,谢谢。我没有想过做一个巨大的联合表并在上面做一个小组。
  • 这就是我现在要做的。在我的数据集上,它是性能最高的。这是经过更新、测试的查询:``` SELECT phone, COUNT(phone) as count FROM ((SELECT phone_main as phone FROM business) UNION ALL (SELECT phone_mobile as phone FROM business) UNION ALL (SELECT phone_tollfree as phone FROM business ) ) 作为组合 WHERE phone '' GROUP BY phone HAVING count > 1 ORDER BY count desc; ```
【解决方案2】:

例如:

SELECT DISTINCT x.* 
  FROM my_table x 
  JOIN my_table y 
    ON y.id <> x.id 
   AND 
     ( y.phone_main     IN(x.phone_main,x.phone_mobile,x.phone_tollfree) 
    OR y.phone_mobile   IN(x.phone_main,x.phone_mobile,x.phone_tollfree) 
    OR y.phone_tollfree IN(x.phone_main,x.phone_mobile,x.phone_tollfree) 
     );

【讨论】:

  • 这可能有效,谢谢!我会测试一下。
  • 所以我尝试了这个并在大约 15 分钟后终止了查询。如果我让它完成,它看起来会起作用,但我可以使用联合策略足够接近,它会生成电话号码,并让程序为每个电话号码选择一组重复项。
【解决方案3】:

你可以这样做:

with 
l as (
  select *, least(phone_main, phone_mobile, phone_tollfree) as p
  from t
)
select *
from l
where p in (select p from l group by p having count(*) > 1)

【讨论】:

  • 我必须阅读一下这个手册,(至少 & with),但我会的,并测试一下,谢谢。
  • 感谢您向我介绍公用表表达式!在这种情况下,我认为 least() 函数实际上会有问题,因为如果 3 列中的任何一个为 null,它将返回 null,但我可以将 with 语句与 @sabasabo 的联合查询一起使用并得到我需要的。
猜你喜欢
  • 2015-11-17
  • 2022-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 2017-02-14
  • 2015-07-17
相关资源
最近更新 更多