2

I have a large (88K rows) table that holds data in pairs.

For a specific entity, there are 2 records, with UID's and then a load of additional data.

I need to take each pair (pairs can be found by matching another ID number) and compare the additional data.

So, I'd find a pair, compare the data and if either of the data values is the same (or different) flag that pair (and allow me to potentially run an update on one of the rows)

I can script this out n my PHP application if it requires multiple queries, but if this can be done just in SQL, that'd be great.

Any updates to a specific row would just be change a certain value to 0.

Table:

CREATE TABLE `ad_transitions` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `asset_id` int(11) NOT NULL,
  `left` varchar(50) DEFAULT '0',
  `top` varchar(50) DEFAULT '0',
  `width` varchar(50) DEFAULT '0',
  `height` varchar(50) DEFAULT '0',
  `boundingWidth` varchar(50) DEFAULT NULL,
  `boundingHeight` varchar(50) DEFAULT NULL,
  `fill` varchar(50) DEFAULT '0',
  `shadow` varchar(128) DEFAULT NULL,
  `filter` varchar(512) DEFAULT NULL,
  `overlayFill` varchar(50) DEFAULT NULL,
  `opacity` varchar(50) DEFAULT '1',
  `scaleX` varchar(50) DEFAULT '1',
  `scaleY` varchar(50) DEFAULT '1',
  `angle` varchar(50) DEFAULT '0',
  `wait` int(11) DEFAULT '0',
  `duration` int(11) DEFAULT '0',
  `easing` varchar(50) DEFAULT 'Linear.easeNone',
  `originX` varchar(128) DEFAULT 'center',
  `originY` varchar(128) DEFAULT 'center',
  PRIMARY KEY (`id`)
)

Data:

INSERT INTO `database`.`ad_transitions` (`id`, `asset_id`, `left`, `top`, `width`, `height`, `boundingWidth`, `boundingHeight`, `fill`, `shadow`, `filter`, `overlayFill`, `opacity`, `scaleX`, `scaleY`, `angle`, `wait`, `duration`, `easing`, `originX`, `originY`) VALUES ('497', '161', '0', '0', '1280', '720', NULL, NULL, '#000000', NULL, NULL, NULL, '0', '1', '1', '0', '0', '0', 'Linear.easeNone', 'left', 'top');
INSERT INTO `database`.`ad_transitions` (`id`, `asset_id`, `left`, `top`, `width`, `height`, `boundingWidth`, `boundingHeight`, `fill`, `shadow`, `filter`, `overlayFill`, `opacity`, `scaleX`, `scaleY`, `angle`, `wait`, `duration`, `easing`, `originX`, `originY`) VALUES ('498', '161', '0', '0', '1280', '720', NULL, NULL, '#000000', NULL, NULL, NULL, '1', '1', '1', '0', '0', '5000', 'Linear.easeNone', 'left', 'top');
INSERT INTO `database`.`ad_transitions` (`id`, `asset_id`, `left`, `top`, `width`, `height`, `boundingWidth`, `boundingHeight`, `fill`, `shadow`, `filter`, `overlayFill`, `opacity`, `scaleX`, `scaleY`, `angle`, `wait`, `duration`, `easing`, `originX`, `originY`) VALUES ('499', '162', '269.16666666667', '-104', '986', '104', NULL, NULL, '#000000', NULL, NULL, NULL, '1', '1', '1', '0', '0', '0', 'Linear.easeNone', 'left', 'top');
INSERT INTO `database`.`ad_transitions` (`id`, `asset_id`, `left`, `top`, `width`, `height`, `boundingWidth`, `boundingHeight`, `fill`, `shadow`, `filter`, `overlayFill`, `opacity`, `scaleX`, `scaleY`, `angle`, `wait`, `duration`, `easing`, `originX`, `originY`) VALUES ('500', '162', '269.16666666667', '24', '986', '104', NULL, NULL, '#000000', NULL, NULL, NULL, '1', '1', '1', '0', '5000', '1000', 'Bounce.easeOut', 'left', 'top');
0

1 Answer 1

1

You can do this in SQL and make it very efficient at the same time. Essentially what we'll do is join the table to itself on your two Ids. Once you have a full set of all matching IDs you can compare the additional field values. To do this efficiently you can build them out into a single string, and hash it, then compare the hashes. It is exceptionally efficient and effective. Abbreviated example below.

SELECT
     id
    ,asset_id
FROM
(
 SELECT
     id
    ,asset_id
    ,SHA1(left + '|' + top) As DataCompare
    FROM ad_transitions
) As FirstSet
JOIN
(
 SELECT
     id
    ,asset_id
    ,SHA1(left + '|' + top) As DataCompare
    FROM ad_transitions
) As SecondSet
    ON FirstSet.id = SecondSet.id
    AND FirstSet.asset_id = SecondSet.asset_id
WHERE FirstSet.DataCompare = SecondSet.DataCompare

The pipe is added to the end of each field string (convert where necessary) to prevent issues that could result from odd but always possible data patterns such as the following:

Name     RandomText
Joh      Normand
John     Ormand

If just these two items are hashed, as is, they will be identical, despite they clear fact they are very different. The addition of a pipe after the field fixes johnnormand to joh|normand and john|ormand ensuring a unique hash and thus no accidental duplicate detection.

3
  • OK, so I ran this query on my data, and the results are a tad confusing and I can't see how I'd use them to attempt a targeted update. So, if of both values match for both rows, I see 4 results. If there is a mismatch in on set of values, there are 2 results shown (the results are the ones that match). So, I can kind of see which sets match across the board, but I need to be able to do an update on one of the rows in the pair.
    – Mr Pablo
    Nov 16, 2015 at 17:08
  • If you select the IDs of rows that have matching IDs and hashes you have your full set of duplicated data. You just need to determine which of those rows to update then... use whatever appropriate logic to choose the update row or just select 1 at random. If you want to see duplicated IDs with different info just set the hash to <>.
    – Dave
    Nov 16, 2015 at 17:18
  • where do I put the <> to change it to find the differences?
    – Mr Pablo
    Nov 18, 2015 at 17:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.