【问题标题】:MySQL getting duplicates from select distinct + unionMySQL从select distinct + union中获取重复项
【发布时间】:2012-09-12 09:55:01
【问题描述】:

当我在 MySQL 中运行以下查询时,我得到了很多重复项。我知道我已经足够清楚了,我只需要不同的记录,所以我不明白为什么它会为我加倍。当我包含最后一个联合(importorders 表)时,似乎所有重复项都会出现,因为大多数客户在客户和订单中都有相同的地址。谁能帮我理解为什么会这样?

SELECT DISTINCT PostalCode, City, Region, Country
FROM 
(select distinct postalcode, city, region, country
from importemployees
UNION
select distinct postalcode, city, region, country
from importcustomers
UNION
select distinct postalcode, city, region, country
from importproducts
UNION
select distinct shippostalcode as postalcode, shipcity as city, shipregion as region, shipcountry as country
from importorders) T

如您所见。有些行是重复的。

如果我先使用INSERT IGNORE 插入importcustomers,然后插入importorders,那么它会设法将记录识别为重复记录。为什么选择查询不起作用?

【问题讨论】:

  • 重复是什么意思?列还是整行?
  • 我的意思是重复的行。相同行中的值看起来相同。可以前。表中的不同字符集/排序规则(或从 csv 导入时)会触发这个?
  • 我无法重现这个。你能为此发布一个直播sql-fiddle吗?
  • 更好。我从 MySQL 工作台得到了导出。我刚刚导入它并尝试了一些类似上面的查询。不知道错误在哪里,所以如果你可以使用它。学校分配,所以没有保密=)ge.tt/69lmmZN/v/0

标签: mysql


【解决方案1】:

非常奇怪的问题。当我放弃“国家”时,它似乎解决了这个问题。

SELECT DISTINCT PostalCode, City, Region

总共 128 个,查询耗时 0.0066 秒

SELECT DISTINCT PostalCode, City, Region, Country

总共 209 个,查询耗时 0.0002 秒

此外,该行为似乎只影响ImportCustomersImportOrders

SELECT postalcode, city, region, country
FROM 
    (SELECT postalcode, city, region, country FROM importcustomers
    UNION
    SELECT shippostalcode, shipcity, shipregion, shipcountry FROM importorders) t

总共 172 个,查询耗时 0.0053 秒

SELECT postalcode
FROM 
    (SELECT postalcode FROM importcustomers
    UNION
    SELECT shippostalcode FROM importorders) t

总共 91 个,查询耗时 0.0050 秒

然后我将其缩小到importcusotmersimportorders 上的country

SELECT TRIM(country) AS country FROM importcustomers
UNION
SELECT TRIM(shipcountry) AS country FROM importorders
阿根廷
阿根廷
奥地利
奥地利
比利时
比利时
...

当我将专栏投到BINARY时发生了一些有趣的事情

SELECT BINARY country AS country FROM importcustomers
UNION
SELECT BINARY shipcountry AS country FROM importorders
阿根廷
417267656e74696e610d
奥地利
417573747269610d
比利时
42656c6769756d0d
...

ImportOrders 导致重复。

 SELECT BINARY shipcountry AS country FROM importorders
4765726d616e790d
5553410d
5553410d
4765726d616e790d
...

查看您提供的转储,在国家/地区末尾附加了一个额外的\r(在值中由0d 表示)。

-- -- 转储表 `importorders` 的数据 -- 插入“进口订单”值 ...'德国\r'), ...'美国\r'), ...'美国\r'), ...'德国\r'), ...'墨西哥\r'),

importcustomers 中的country 看起来不错:

-- -- 转储表 `importcustomers` 的数据 -- 插入“importcustomers”值 ...'德国', ... , ...'墨西哥', ... , ...'墨西哥', ... , ...'英国', ... , ...'瑞典',...,

您可以通过运行以下查询来删除这些\r(回车):

UPDATE importorders SET ShipCountry = REPLACE(ShipCountry, '\r', '')

然后,如果您运行原始查询,您将获得所需的结果集。仅供参考,如果您使用的是UNION,则不需要DISTINCT

SELECT PostalCode, City, Region, Country
FROM 
    (SELECT postalcode, city, region, country FROM importemployees
    UNION
    SELECT postalcode, city, region, country FROM importcustomers
    UNION
    SELECT postalcode, city, region, country FROM importproducts
    UNION
    SELECT shippostalcode as postalcode, shipcity as city, 
        shipregion as region, shipcountry as country FROM importorders) T

【讨论】:

  • 哇。不错的收获!我自己注意到了 sqldump 中的 \r ,但是由于我是 sql 新手,所以它没有发出任何警报。 \r 是什么符号?因为它没有出现在 GUI 中?非常感谢你也给了我“教程”。又学会了一招! :) 编辑:现在测试它(从 sqldump 中删除所有 \r)。
  • @Graimer \r 是一个回车,它创建一个新行。你可以阅读更多关于它的信息here。您还可以运行查询以删除 \r。请参阅我的更新答案。
  • 您先生,真是个天才! :D 被卡住了一整天。现在我可以删除长插入忽略(和左连接...其中 .. 为空)脚本:D
  • @Graimer 很高兴我能帮上忙 :) 这是一个有趣的挑战!
  • 您也不需要外部的SELECT 语句 - 这里唯一的作用是将列名大写,您可以通过将as PostalCode 等添加到第一个SELECT。您也不需要最后一个SELECT 中的as,它们没有任何作用。
猜你喜欢
  • 2011-10-21
  • 2015-07-20
  • 2020-03-25
  • 1970-01-01
  • 2018-04-19
  • 2015-03-26
  • 2015-06-02
  • 2019-12-09
  • 1970-01-01
相关资源
最近更新 更多