如何查找重复项并更新除最新条目以外的所有条目的列值

时间:2019-03-18 16:29:15

标签: mysql sql database

我有一个表items,其中有列item_idlockup_iddatearchive。我需要能够浏览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 :(得分:0)

看看您的示例,我假设最新的条目是ID最高的条目

如果是这种情况,您可以创建带有列的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

答案 1 :(得分:0)

看起来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
  );

答案 2 :(得分:0)

您可以分两步进行。

首先将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)上有索引应该会非常有效。

Demo

答案 3 :(得分:0)

为了将所有具有相同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的所有项目中的较新项目。