MySQL UNION ALL 问题以获得正确的结果

Posted

技术标签:

【中文标题】MySQL UNION ALL 问题以获得正确的结果【英文标题】:MySQL UNION ALL Issue to get the right result 【发布时间】:2014-04-13 23:58:59 【问题描述】:

看到我不是专家,为此困扰了几个小时。

我有两个表 t1 和 t2,需要更新 t1 中与 t2 匹配的每一行。 t1 包含格式为 xxx-xxx-xxx-xxx-xxx 的 serialkey 字段 t2 包含格式为 xxxxxxxxxxxxxxx 的 serialkey 字段

我以为我可以使用 UNION ALL,但我没有实现我想要做的事情。由于一个表包含带有破折号的序列,我想像这样删除它们。

SELECT serialkey FROM
(SELECT replace(serialkey,'-','') as serialkey FROM t1 
UNION ALL
SELECT serialkey FROM t2 ) tbl
GROUP BY serialkey

我还尝试了 HAVING 计数,但在第一个和第二个版本中,我似乎既无法获得计数,也无法对它们进行分组,以查找 t1 中与 t2 匹配的所有行打算然后更新 t2 中的列以说找到匹配项(这样我只需要运行一次)。

SELECT serialkey
FROM (
SELECT replace(serialkey,'-','') serialkey FROM t1
UNION ALL
SELECT serialkey FROM t2
) tbl
GROUP BY serialkey
HAVING count(*)= 2 <<--- 2 shows none and 1 shows all rows combined
ORDER BY serialkey;

最后请注意,t1 将包含大约 150,000 行,t2 将包含大约 300,000 行; t1 和 t2 之间可能有大约 110,000 个匹配项,我想按上述方式进行编辑(php)。我也尝试了一些左连接,结果在 15 分钟内无法访问 phpmyadmin,这可能是我自己的问题,尽管我猜这个查询相当大,需要最好的代码。

上面的两个结果都只是列出了我在两个表中的所有记录!

任何帮助表示赞赏,谢谢。

克里斯

【问题讨论】:

【参考方案1】:

在一个表中格式化 serialkey 值并在另一个表中未格式化几乎会扼杀优化查询的任何机会,但是对于 300K 行,它不应该花费 那么 长 - 可能需要几秒钟而不是超过几分钟。

基本上你需要的是INNER JOIN。这将为您提供t1t2 中的所有串行密钥的列表:

SELECT t1.SerialKey
FROM t1
JOIN t2 ON REPLACE(t1.SerialKey, '-', '') = t2.SerialKey

您可以在更新中使用相同的连接逻辑:

UPDATE t1
JOIN t2 ON REPLACE(t1.SerialKey, '-', '') = t2.SerialKey
SET t1.whatever = 'whatever'

【讨论】:

做了一个快速测试,有趣的是,我采用这种方法得到了零结果。不确定那是什么,因为您的建议确实有意义。等我睡了一会儿再试。 好的,祝你好运!我会确保带有破折号的序列号在t1 而不是t2;这是唯一会弄乱查询的东西(除了没有实际匹配)。 所以我找不到任何匹配的原因;一个导入在 serialkey 字段中有换行代码。刚刚执行了您的建议,并等待了几分钟的 godaddy myphpadmin 响应(所以发生了一些事情,但如果它没有很快再次超时,将是几分钟)。应该将这两个字段都设置为唯一字段还是索引以加快速度? 部分测试需要 883 秒,很吓人,但这确实有效。我想我需要找到一种方法在 php 端循环 x 次而不是杀死东西。【参考方案2】:
UPDATE t1,t2 
SET t1.serialkey = t2.serialkey
WHERE t2.serialkey = REPLACE( t1.serialkey,  '-',  '')

我假设您想从 t2 复制序列号,如果匹配,则在 t1 中插入不带破折号的序列号。请不要在没有备份的情况下在真实数据库中使用此查询:)

【讨论】:

以上是关于MySQL UNION ALL 问题以获得正确的结果的主要内容,如果未能解决你的问题,请参考以下文章

MySQL中使用union all获得并集的排序

mysql union和union all的区别

使用UNION ALL和子查询和变量的MySQL错误

如何使用 Union all 获得两列结果

MySQL union all排序问题

mysql中的union和union all有啥区别? [复制]