用于更新重复记录的SQL语句,保持1条记录不变

时间:2013-01-27 10:52:19

标签: php mysql sql

我需要帮助来获得这种情况的解决方案。我有一个包含记录的表,有一个字段sku,在这个记录中我有多次出现sku。表结构就像这个rid | id | sku | name

如果桌面上有任何sku多次可用,则记录如下所示

rid  id  sku     name
---  --  ------  --------------

1    3   rs-123  test product

2    3   rs-123  test product

3    4   rs-125  test product 2

4    4   rs-125  test product 2

5    4   rs-125  test product 2

6    6   rs-126  test product 3

我需要的是使用重复记录更新表,保持第一条记录不变(N-1)。因此,例如我需要运行仅更新重复记录的SQL语句,因此如果第一条记录更新,它将如下所示

rid  id  sku     name
---  --  ------  --------------
1    3   rs-123  test product
2    3   updated  updated 

我试图通过这个SQL语句实现某些功能,但它无法正常工作

WITH duplicates AS (
  SELECT
ROW_NUMBER() OVER (PARTITION BY id ORDER BY rid) AS duplicate_id,
*
FROM
test
)

UPDATE
  duplicates
SET
  sku = updated
WHERE
  duplicate_id > 1

任何建议都将受到高度赞赏。

3 个答案:

答案 0 :(得分:1)

也许您可以尝试使用变量:

SQLFIDDLE DEMO

set @sku:='';

select a.rid, a.id, 
@sku:= (case when @sku<>a.sku
        then a.sku else 'updated'
        end) as skus, @sku:=a.sku, a.name
from skus a
;

| RID | ID |    SKUS | @SKU:=A.SKU |           NAME |
-----------------------------------------------------
|   1 |  3 |  rs-123 |      rs-123 |   test product |
|   2 |  3 | updated |      rs-123 |   test product |
|   3 |  4 |  rs-125 |      rs-125 | test product 2 |
|   4 |  4 | updated |      rs-125 | test product 2 |
|   5 |  4 | updated |      rs-125 | test product 2 |
|   6 |  6 |  rs-126 |      rs-126 | test product 3 |

更新:

SQLFIDDLE DEMO for UPDATING

set @sku:='';

UPDATE
  skus a
  join 
  (select a.rid, a.id, 
@sku:= (case when @sku<>a.sku
        then a.sku else 'updated'
        end) as skus, @sku:=a.sku, a.name
from skus a) b
  on a.rid = b.rid
SET
  a.sku = 'up_again'
WHERE
  b.skus = 'updated'
;

| RID | ID |      SKU |           NAME |
----------------------------------------
|   1 |  3 |   rs-123 |   test product |
|   2 |  3 | up_again |   test product |
|   3 |  4 |   rs-125 | test product 2 |
|   4 |  4 | up_again | test product 2 |
|   5 |  4 | up_again | test product 2 |
|   6 |  6 |   rs-126 | test product 3 |

这是另一个使用Joins

http://sqlfiddle.com/#!2/ddf47/2

update skus a
join skus b
on a.rid = b.rid +1
set a.sku = 'updated'
where a.sku = b.sku
;


| RID | ID |     SKU |           NAME |
---------------------------------------
|   1 |  3 |  rs-123 |   test product |
|   2 |  3 | updated |   test product |
|   3 |  4 |  rs-125 | test product 2 |
|   4 |  4 | updated | test product 2 |
|   5 |  4 | updated | test product 2 |
|   6 |  6 |  rs-126 | test product 3 |

更新sku和名称:

http://sqlfiddle.com/#!2/97f4f/1

update skus a
join skus b
on a.rid = b.rid +1
set a.sku = 'updated', a.name = 'new_name'
where a.sku = b.sku
;

| RID | ID |     SKU |           NAME |
---------------------------------------
|   1 |  3 |  rs-123 |   test product |
|   2 |  3 | updated |       new_name |
|   3 |  4 |  rs-125 | test product 2 |
|   4 |  4 | updated |       new_name |
|   5 |  4 | updated |       new_name |
|   6 |  6 |  rs-126 | test product 3 |

在SQL SERVER

中使用ROW_NUMBER()查看OP的问题

http://sqlfiddle.com/#!3/355c4/2

update a 
set a.sku = 'updated', a.name = 'new_name'
from skus a
join (Select rid, id, row_number() over (
  partition by id order by rid asc) rank
from skus) b
on a.rid = b.rid
where b.rank > 1
;

| RID | ID |     SKU |           NAME |
---------------------------------------
|   1 |  3 |  rs-123 |   test product |
|   2 |  3 | updated |       new_name |
|   3 |  4 |  rs-125 | test product 2 |
|   4 |  4 | updated |       new_name |
|   5 |  4 | updated |       new_name |
|   6 |  6 |  rs-126 | test product 3 |

答案 1 :(得分:0)

试试这个:

UPDATE
  test
SET
  sku = 'updatedSKU'
WHERE rid IN
(
  SELECT
    rid
  FROM
  (
    SELECT rid,
        @rn := IF(@sku != sku, 1, @rn + 1) rn,
        @sku:=sku
     FROM test,
        (SELECT @rn:=0, @sku := NULL) r
  ) s
  WHERE rn > 1
);

<强> SQL FIDDLE DEMO

或者这个:

UPDATE
   test t
   JOIN
     (
       SELECT rid,
           CASE WHEN @sku != sku THEN @rn := 1 ELSE @rn := @rn + 1 END rn,
           @sku:=sku
        FROM test,
          (SELECT @rn:=0, @sku := NULL) r
     ) s
  ON t.rid = s.rid
  SET  sku = 'updatedSKU'
  WHERE s.rn > 1;

<强> SQL FIDDLE DEMO

答案 2 :(得分:0)

假设rid是唯一的,这个版本可以在不依赖数据顺序的情况下工作。

update skus, (
       select id, min(rid) rid from skus group by id 
) minimum_rid
set skus.sku = 'updated'
, skus.name = 'updated'
where skus.id = minimum_rid.id
and skus.rid > minimum_rid.rid ;