2016-06-01 49 views
0

我有两个来自不同服务器的相同表。作为一个简短的修复(以帮助处理更长的修复,因为我们正在处理非常遗留的基础架构)来识别重复的PK,我们已经决定让第一阶段收集其主数据库中其主数据库存在的记录列表是相同的。即使它们具有相同的PK,但它们在其他元组(或记录)中仍然具有不同的数据,例如名字,姓氏等。UNION声明不起作用,被迫使用JOIN(由任一性能支配?)

我想使用此UNION语句,因为它们都是相同的表,但不断收到

SELECT T.`hospitalno` AS HospitalnoMain, T.`dateencoded` AS DateEncodedMain, 
    T.`firstname` AS FirstNameMain, T.`lastname` AS LastNameMain 
FROM registration.`patmaster` T 
UNION 
SELECT P.`hospitalno` AS HospitalnoAux, P.`dateencoded` AS DateEncodedAux, 
    P.`firstname` AS FirstNameAux, P.`lastname` AS LastNameAux 
FROM registration.`patmaster` P 
WHERE T.`LastNameMain` <> P.`LastNameAux` AND T.`FirstNameMain` <> P.`FirstNameAux` 
LIMIT 100 

所以我已经决定在这个声明是拉正确的数据(通过所有的调整,至少“在‘去哪儿’子句中的列未知”的错误,以记录来测试查询,这是正确的)。

SELECT * FROM 
(
    SELECT T.`hospitalno` AS HospitalnoMain, T.`dateencoded` AS DateEncodedMain, 
     T.`firstname` AS FirstNameMain, T.`lastname` AS LastNameMain 
    FROM registration.`patmaster` t 
) AS G 
LEFT OUTER JOIN 
(
    SELECT P.`hospitalno` AS HospitalnoAux, P.`dateencoded` AS DateEncodedAux, 
     P.`firstname` AS FirstNameAux, P.`lastname` AS LastNameAux 
    FROM registration.`patmaster` p 
) H 
    ON G.HospitalnoMain = H.HospitalnoAux 
WHERE G.`LastNameMain` <> H.`LastNameAux` AND G.`FirstNameMain` <> H.`FirstNameAux` 
LIMIT 100 

- 请原谅手动输入格式。

我的问题是,这是更好的性能明智,因为它会通过两张表拉大量的数据。如果是UNION,那么我的UNION语句有什么问题,因为我尝试了SELECT语句的变体,它会一直给我提供相同的“未知列...”错误。预先感谢您

编辑 也,如果有人知道如何使用SQL中的“代码”,我将不胜感激。它似乎没有在这里工作,因为

+0

我想你误会了'UNION'的用法 – Fabricator

+0

我相信你的UNION由于你的WHERE子句而失败。为了它的工作,每个查询应该独立,并返回相同的列名(我相信相同的顺序,但我不积极)。将引擎想象为将一个结果集合堆叠在另一个上面。您的where子句失败,因为它在第二个查询中查找表T,但第二个查询中没有表T.一旦你得到它的工作,我相信你会想要使用UNION ALL而不仅仅是一个UNION(没有ALL,你试图找到的重复行将被合并成一行) – Ben

+0

这些查询返回不同的东西。你还没有告诉我们这些查询应该返回哪些行。而且你还没有告诉我们什么(可能是第三个)查询的结果实际上是你需要的。 – philipxy

回答

2

你的left join是好的。 。 。假设它做你想要的。但是,如果不需要它们,请不要在from子句中使用子查询。 MySQL实现了这样的子查询,导致额外的开销。

SELECT T.`hospitalno` AS HospitalnoMain, T.`dateencoded` AS DateEncodedMain, 
     P.`hospitalno` AS HospitalnoAux, P.`dateencoded` AS DateEncodedAux, P.`firstname` AS FirstNameAux, P.`lastname` AS LastNameAux 
FROM registration.`patmaster` t INNER JOIN 
    registration.`patmaster` p 
    ON p.hospitalno = t.hospitalno 
WHERE t.`LastNameMain` <> p.`LastName` AND t.`FirstNameMain` <> p.`FirstName` 
LIMIT 100; 

注:where子句将外连接成一个内圈反正加盟,让人们有理由使外连接。

1

请注意,此查询(与原始数据类似)将拉取行的重复副本,其中一行的“主”和“辅助”值颠倒过来。

在更一般的情况下,如果名字或姓氏可能为NULL,我们可以使用空对比<=>(太空飞船)运算符,因此比较将只返回TRUE或FALSE,而不返回空值。

SELECT t.`hospitalno` AS HospitalnoMain 
    , t.`dateencoded` AS DateEncodedMain 
    , t.`firstname`  AS FirstNameMain 
    , t.`lastname`  AS LastNameMain 
    , p.`hospitalno` AS HospitalnoAux 
    , p.`dateencoded` AS DateEncodedAux 
    , p.`firstname`  AS FirstNameAux 
    , p.`lastname`  AS LastNameAux 
FROM registration.`patmaster` t 
LEFT 
JOIN registration.`patmaster` p 
    ON p.hospitalno = t.hospitalno 
     AND NOT (t.firstname <=> p.firstname) 
     AND NOT (t.lastname <=> p.lastname )