MySQL: поиск дубликатов в нескольких полях - PullRequest
1 голос
/ 21 июля 2011

Предыстория: у моего работодателя есть база данных, основанная на действительно старой версии MySQL (3.23). Меня попросили найти дубликаты серийных номеров и MAC-адресов в базе данных.

Мне удалось найти повторяющиеся серийные номера, но, поскольку эта версия MySQL не поддерживает подзапросы, мне пришлось прибегнуть к использованию временной таблицы. Вот два оператора SQL, которые я использовал в итоге:

CREATE TEMPORARY TABLE IF NOT EXISTS Inventory_Duplicate_Serials
SELECT Serial
FROM Inventory
WHERE Serial IS NOT NULL
GROUP BY Serial
HAVING COUNT(Serial) > 1

SELECT DeviceName, Model, Inventory.Serial
FROM Inventory
INNER JOIN Inventory_Duplicate_Serials
ON Inventory.Serial = Inventory_Duplicate_Serials.Serial
ORDER BY Serial

Теперь мне нужно найти дубликаты MAC-адресов. Проблема в том, что в таблице «Инвентаризация» есть три поля MAC-адреса (MAC, MAC2 и MAC3). Так, например, если значение поля «MAC» элемента совпадает со значением поля «MAC2» другого элемента, мне нужно знать об этом. Как мне это сделать? Спасибо за ваше время.


ОБНОВЛЕНИЕ: Решено. В итоге я создал две временные таблицы (Inventory_All_MACs и Inventory_Duplicate_MACs). Это пять запросов:

CREATE TEMPORARY TABLE IF NOT EXISTS Inventory_All_MACs
SELECT MAC
FROM Inventory
WHERE MAC != ''

CREATE TEMPORARY TABLE IF NOT EXISTS Inventory_All_MACs
SELECT MAC2 AS MAC
FROM Inventory
WHERE MAC2 != ''

CREATE TEMPORARY TABLE IF NOT EXISTS Inventory_All_MACs
SELECT MAC3 AS MAC
FROM Inventory
WHERE MAC3 != ''

CREATE TEMPORARY TABLE IF NOT EXISTS Inventory_Duplicate_MACs
SELECT MAC
FROM Inventory_All_MACs
GROUP BY MAC
HAVING COUNT(MAC) > 1

SELECT DeviceName, Model, Inventory_Duplicate_MACs.MAC AS DuplicateMAC, Inventory.MAC, MAC2, MAC3
FROM Inventory_Duplicate_MACs
INNER JOIN Inventory
ON Inventory.MAC  = Inventory_Duplicate_MACs.MAC
OR Inventory.MAC2 = Inventory_Duplicate_MACs.MAC
OR Inventory.MAC3 = Inventory_Duplicate_MACs.MAC
ORDER BY Inventory_Duplicate_MACs.MAC, DeviceName, Model

Спасибо всем!

Ответы [ 3 ]

1 голос
/ 21 июля 2011

«Простое» решение, которое приходит на ум, - это создать вторую временную таблицу, в которой перечислены все MAC-адреса в одном столбце, поэтому вам потребуется создать три записи для одной записи из первой временной таблицы.

0 голосов
/ 21 июля 2011
CREATE TEMPORARY TABLE IF NOT EXISTS Inventory_Mac
  SELECT Mac
  FROM Inventory

INSERT INTO Inventory_Mac
  SELECT Mac2
  FROM Inventory

INSERT INTO Inventory_Mac
  SELECT Mac3
  FROM Inventory

CREATE TEMPORARY TABLE IF NOT EXISTS Inventory_Duplicate_Mac
  SELECT Mac, COUNT(*) AS cnt
  FROM Inventory_Mac
  GROUP BY Mac
  HAVING COUNT(*) > 1


SELECT DeviceName, Model, im.Mac, i.Mac, i.Mac2, i.Mac3
FROM Inventory_Duplicate_Mac AS im
  JOIN Inventory AS i
    ON    i.Mac  = im.Mac
       OR i.Mac2 = im.Mac
       OR i.Mac3 = im.Mac
ORDER BY im.Mac
0 голосов
/ 21 июля 2011

Не уверен на 100% в этом ответе, но стоит попробовать ЛЕВЫЕ СОЕДИНЕНИЯ, например:

SELECT address1
FROM addresses
LEFT JOIN Inventory_Duplicate_Addresses ad1
ON Addresses.MAC = ad1.mac
LEFT JOIN Inventory_Duplicate_Addresses ad2
ON Addresses.MAC = ad2.mac2
LEFT JOIN Inventory_Duplicate_Addresses ad3
ON Addresses.MAC = ad3.mac3
...