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
。这将为您提供t1
和t2
中的所有串行密钥的列表:
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 问题以获得正确的结果的主要内容,如果未能解决你的问题,请参考以下文章