Как найти дубликат и обновить значение столбца для всех, кроме самой последней записи - PullRequest
2 голосов
/ 18 марта 2019

У меня есть таблица items со столбцами item_id, lockup_id, date, archive.Мне нужно иметь возможность пройти через столбец lookup_id и определить дубликаты, меняя значение archive на 1 на каждом дубликате, КРОМЕ новейшей записи в таблице.

item_id       Lookup_id      date     archive
------------------------------------------------
1234            4           1-1-19       0
1235            4           1-1-19       0
1236            4           1-1-19       0
1237            2           1-1-19       0
1238            1           1-1-19       0
1239            1           1-1-19       0

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

'SELECT  `item_id` ,  `lookup_id`, `date`, `archive`
 FROM  items 
 WHERE  `item_id` 
 IN (
    `SELECT  `item_id` 
     FROM  items
     GROUP BY  `item_id` 
     HAVING COUNT(  `item_id` ) >1
)
ORDER BY  `item_id`;

Ответы [ 4 ]

0 голосов
/ 18 марта 2019

Чтобы заархивировать все элементы с одним и тем же lookup_id, кроме более нового, вы можете использовать эту инструкцию sql

UPDATE tn SET tn.archive = 1 
FROM table_name tn
WHERE (SELECT COUNT(tn2.id) FROM table_name AS tn2 WHERE tn2.lookup_id = tn.lookup_id) > 1 
AND tn.id NOT IN (SELECT tn2.id FROM table_name AS tn2 WHERE tn2.lookup_id = tn.lookup_id ORDER BY tn.date DESC, tn.id DESC LIMIT 1);

Сначала в условиях where мы проверяем, существует ли более одного элемента с одинаковым lookup_idи затем мы проверяем, что фактический элемент не является новым из всех элементов с одинаковым lookup_id.

0 голосов
/ 18 марта 2019

Похоже, item_id является последовательным, предполагая, что самая новая запись имеет самое высокое item_id, вы можете отфильтровать по наибольшему item_id для каждого lookup_id, а затем обновить все записи, кроме этих.

update items set archive = 1
where item_id not in 
  (
    select max(item_id) from items 
    group by lookup_id
  );
0 голосов
/ 18 марта 2019

Вы можете сделать это в два шага.

Сначала установите все значения в archive на 1:

update items set archive = 1 where 1;

Затем установите archive = 0 только для "самых новых" записей:

update items i
inner join (
  select max(item_id) as item_id
  from items
  group by Lookup_id
) x using(item_id)
set i.archive = 0;

Вы получите следующий результат:

item_id     Lookup_id   date    archive
   1234             4   1-1-19        1
   1235             4   1-1-19        1
   1236             4   1-1-19        0
   1237             2   1-1-19        0
   1238             1   1-1-19        1
   1239             1   1-1-19        0

Этот метод должен быть достаточно эффективным с индексом (Lookup_id, item_id).

Демо

0 голосов
/ 18 марта 2019

Глядя на ваш пример, я предполагаю, что последняя запись - это запись с наибольшим идентификатором элемента

в этом случае вы можете создать CTE со столбцом и использовать номер строки / раздел с помощью

Примерно так - объединение будет меняться в зависимости от того, какие столбцы уникальны

 ;WITH cte_test  AS
 (SELECT item_id , lookup_id , ROW_NUMBER() OVER (PARTITION BY lookup_id  ORDER BY item_id ) AS rn 
 FROM items ) 
 UPDATE it2
  SET it2.archive = 1
  FROM items it2
  INNER JOIN cte_test ct 
  ON ct.item_id = it2.item_id
  AND ct.lookup_id = it2.lookup_id where rn > 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...