В MySQL (5.1) лучший способ обнаружить один набор столбцов не равен другому - PullRequest
2 голосов
/ 27 июля 2011

У меня есть две таблицы: источник и пункт назначения. Я хочу пометить таблицу назначения для обновления, если какой-либо из соответствующих столбцов в исходных столбцах отличается. Столбцы могут быть нулевыми.

В настоящее время это кажется очень неуклюжим:

UPDATE destination d
JOIN source s
   ON d.id = s.id
SET d.updateFlag = 1
WHERE (    (d.col1 IS NULL AND s.col1 IS NOT NULL) 
        OR (d.col1 IS NOT NULL AND s.col1 IS NULL)
        OR (d.col1 <> s.col1)
      )
      OR
      (    (d.col2 IS NULL AND s.col2 IS NOT NULL) 
        OR (d.col2 IS NOT NULL AND s.col2 IS NULL)
        OR (d.col2 <> s.col2)
      )
      ...etc...
      OR
      (    (d.colN IS NULL AND s.colN IS NOT NULL) 
        OR (d.colN IS NOT NULL AND s.colN IS NULL)
        OR (d.colN <> s.colN)
      )

В идеале я мог бы сделать что-то вроде:

UPDATE destination d
JOIN source s
   ON d.id = s.id
SET d.updateFlag = 1
WHERE HASH(d.col1,d.col2,...etc...,d.colN) <> HASH(s.col1,s.col2,...etc...,s.colN)

Некоторая дополнительная информация. Все столбцы имеют разные типы данных (некоторые целые, некоторые биты, некоторые строки) и мы используем разновидность MySQL 5.1.

Ответы [ 2 ]

2 голосов
/ 27 июля 2011

Вы можете упростить свой оператор, используя NULL-safe равный оператор:

UPDATE destination d
JOIN source s
   ON d.id = s.id
SET d.updateFlag = 1
WHERE !(d.col1 <=> s.col1)
   OR !(d.col2 <=> s.col2)
...etc

В качестве альтернативы, вы можете использовать UNION для поиска дублирующихся строк:

  SELECT tbl, id, col1, col2, col3
    FROM (
  SELECT 't1' AS tbl, id, col1, col2, col3
    FROM t1
   UNION ALL
  SELECT 't2' AS tbl, id, col1, col2, col3
    FROM t2
       ) tmp
GROUP BY id, col1, col2, col3 HAVING COUNT(*) = 1;

Затем вы можете использовать полученный результат в своем запросе на обновление:

UPDATE destination d
   SET d.updateFlag = 1
 WHERE EXISTS (
    SELECT NULL FROM (
        SELECT id, col1, col2, col3 FROM t1
        UNION All
        SELECT id, col1, col2, col3 FROM t2
     ) tmp
     WHERE d.id = tmp.id
  GROUP BY id, col1, col2, col3
    HAVING COUNT(*) = 1
)
1 голос
/ 27 июля 2011

Возможно, вы захотите проверить mk-table-checkum , который является одним из инструментов Maatkit . Это делает то, что вы описываете, вычисляя контрольную сумму для всей строки и сравнивая ее с соответствующей строкой в ​​другой базе данных.

Многие люди используют этот инструмент для проверки того, что ведомое устройство является точной копией своего главного устройства, но вы можете сравнить любые две базы данных, которые имеют схожие метаданные.

...