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

时间:2014-04-13 23:58:59

标签: php mysql union-all

在这看到我不是专家的情况下,我一直在困扰几个小时。

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

的串行字段

我以为我可以使用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匹配的所有行意图然后更新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)。我尝试了一些左连接,最终无法访问phpmyadmin 15分钟,可能是我自己的坏,虽然我猜这个查询相当大,需要最好的代码。

上述两个结果都只是列出了两张桌子的所有记录!

感谢任何帮助,谢谢。

克里斯

2 个答案:

答案 0 :(得分: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'

答案 1 :(得分:0)

UPDATE t1,t2 
SET t1.serialkey = t2.serialkey
WHERE t2.serialkey = REPLACE( t1.serialkey,  '-',  '')

我假设您要从t2复制序列号,如果匹配则在t1中插入没有短划线的序列号。如果没有备份,请不要在真正的数据库中使用此查询:)