Как проверить каждую строку (отметка времени - 60 секунд), чтобы определить, есть ли дубликаты данных или нет в MySQL? - PullRequest
0 голосов
/ 07 января 2019

У меня есть такой стол

table data will be like this

Вы увидите, что красный крест со знаком - это результат, который я хочу. Я хочу переместить знак Красного Креста в таблицу журналов ошибок, поскольку он указывает на дубликаты данных.

Чтобы определить дубликаты данных:

  1. найти данные за 60 секунд до отметки времени каждой строки
  2. тот же идентификатор рекламодателя, идентификатор предложения, идентификатор комиссии, идентификатор комиссии, идентификатор объявления, идентификатор публикатора, идентификатор публикации, идентификатор источника

Пример:

1545981655
1545981657 x -> will marked as duplicate because 1545981657 - 60 = 1545981597. Search first data > 1545981597 except this line. 1545981655 will return.
1545981660 x -> will marked as duplicate because 1545981660 - 60 = 1545981600. Search first data > 1545981600 except this line. 1545981655 will return.
1545981662 x -> will marked as duplicate because 1545981662 - 60 = 1545981602. Search first data > 1545981602 except this line. 1545981655 will return.
1545981707  -> won't marked as duplicate because 1545981707 - 60 = 1545981647. Search first data > 1545981647 except this line. 1545981655 won't return because publisher_asset_id is different.
1545981710 x -> will marked as duplicate because 1545981710 - 60 = 1545981650. Search first data > 1545981650 except this line. 1545981707 will return.
1545981712 x -> will marked as duplicate because 1545981712 - 60 = 1545981652. Search first data > 1545981650 except this line. 1545981707 will return.
1545981714 x -> will marked as duplicate because 1545981714 - 60 = 1545981654. Search first data > 1545981654 except this line. 1545981707 will return.
1545981718  -> won't marked as duplicate because 1545981718 - 60 = 1545981658. Search first data > 1545981658 except this line. No data returns, because pubisher_asset_id is different

Как добиться этого в запросе mysql, а не в цикле по всем данным?

Результат, который я хочу достичь следующим образом:

result table want to achieve

Ребята, вам нужна помощь. Большое вам спасибо.

1 Ответ

0 голосов
/ 07 января 2019

Переименуйте таблицу T в свою таблицу и попробуйте это:

SELECT * FROM (
SELECT id, advertiser_id, offer_id, commission_id, commission_tier_id, creative_id, publisher_id, publisher_asset_id, source_id, impression_timestamp,
COUNT(*) OVER (PARTITION BY advertiser_id, offer_id, commission_id, commission_tier_id, creative_id, publisher_id, publisher_asset_id, source_id ORDER BY impression_timestamp RANGE 60 PRECEDING) AS DuplicateFlag
FROM T
) DetectDuplicate
WHERE DuplicateFlag > 1

EDIT : до MySQL 8 вышеуказанный запрос не мог быть выполнен и должен быть заменен запросом с JOIN (к сожалению, немного медленнее):

SELECT DISTINCT T2.*
FROM T T1
LEFT OUTER JOIN T T2
  ON T1.id                   <> T2.id
 AND T1.advertiser_id         = T2.advertiser_id
 AND T1.offer_id              = T2.offer_id
 AND T1.commission_id         = T2.commission_id
 AND T1.commission_tier_id    = T2.commission_tier_id
 AND T1.creative_id           = T2.creative_id
 AND T1.publisher_id          = T2.publisher_id
 AND T1.publisher_asset_id    = T2.publisher_asset_id
 AND T1.source_id             = T2.source_id
 AND T1.impression_timestamp >= T2.impression_timestamp - 60
WHERE T2.id IS NOT NULL

Возможен как минимум один другой синтаксис, такой как:

SELECT *
FROM T Main
WHERE EXISTS (
    SELECT 1
    FROM T
   WHERE id                   <> Main.id
     AND advertiser_id         = Main.advertiser_id
     AND offer_id              = Main.offer_id
     AND commission_id         = Main.commission_id
     AND commission_tier_id    = Main.commission_tier_id
     AND creative_id           = Main.creative_id
     AND publisher_id          = Main.publisher_id
     AND publisher_asset_id    = Main.publisher_asset_id
     AND source_id             = Main.source_id
     AND impression_timestamp >= Main.impression_timestamp - 60
)
...