对于具有多个行sql相同值的列,将值更新为null

时间:2019-07-18 16:31:59

标签: sql sql-server

表数据就像

+------+---------------+-----
| item | MFGPN         |value |
+------+---------------+-----
| 1    | Z363700Z01    |100   |
+------+---------------+-----
| 2    | Z363700Z01    |200   |
+------+---------------+-----
| 3    | 0119-960-1    |200   |
+------+---------------+-----
| 4    | 445-3-1234    |100   |
+------+---------------+-----

我必须检查不同的id是否具有相同的MFGPN。在这种情况下,对于id 1和2我们具有相同的MFGPN。

如何为这些情况设置一些等级,并且ID 1和2的等级应该相同?

现在对于ID 1和2的相同等级,而不是“值”列中的某些数据,我需要更新null

数据应如下所示:

+------+---------------+-----
| item | MFGPN         |value |rank
+------+---------------+-----
| 1    | Z363700Z01    |null  |1
+------+---------------+-----
| 2    | Z363700Z01    |null  |1
+------+---------------+-----
| 3    | 0119-960-1    |200   |2
+------+---------------+-----
| 4    | 445-3-1234    |100   |3
+------+---------------+-----

2 个答案:

答案 0 :(得分:0)

您可以使用dense_rank()case表达式:

select t.*,
       (case when count(*) over (partition by mfgpn) = 1 then value end) as new_value,
       dense_rank() over (order by mfgpn) as rank
from t;

注意:这会分配排名,但最高排名是基于字母顺序而不是重复项或商品ID的数量。

如果您只想更新值:

with toupdate as (
      select t.*,
             (case when count(*) over (partition by mfgpn) = 1 then value end) as new_value
      from t
     )
update toupdate
    set value = new_value
    where value <> new_value;

答案 1 :(得分:0)

这里是一个示例SQL Fiddle。 (我假设表名称为items。)

如果您只是想清除重复的MFGPN的值,则可以执行以下操作:

-- If you just want to update the value for duplicates
UPDATE  items
SET     value = NULL
WHERE   MFGPN IN (
            SELECT  MFGPN
            FROM    items
            GROUP BY MFGPN
            HAVING  COUNT(item) > 1
        );

但是,我不确定目的是什么,所以这里有一个查询用来调试数据:

-- Subquery with MIN/MAX/COUNT for debugging purposes
SELECT  t.*
    ,   u.*
FROM items t
    INNER JOIN (
        SELECT  t.MFGPN
            ,   MIN(t.item)   AS min_item
            ,   MAX(t.item)   AS max_item
            ,   COUNT(t.item) AS count_item
            ,   ROW_NUMBER() OVER (ORDER BY t.MFGPN) AS rnum_item
        FROM    items t
        GROUP BY t.MFGPN
    ) u ON t.MFGPN = u.MFGPN;

-- Results: http://sqlfiddle.com/#!18/1740d0/1/1
| item |      MFGPN | value |      MFGPN | min_item | max_item | count_item | rnum_item |
|------|------------|-------|------------|----------|----------|------------|-----------|
|    3 | 0119-960-1 |   200 | 0119-960-1 |        3 |        3 |          1 |         1 |
|    4 | 445-3-1234 |   100 | 445-3-1234 |        4 |        4 |          1 |         2 |
|    1 | Z363700Z01 |   100 | Z363700Z01 |        1 |        2 |          2 |         3 |
|    2 | Z363700Z01 |   200 | Z363700Z01 |        1 |        2 |          2 |         3 |

这是SQL Fiddle Schema(用于测试和完整示例):

CREATE TABLE items (
    item    int             PRIMARY KEY,
    MFGPN   varchar(256)    NOT NULL,
    value   varchar(64)
);

INSERT items
VALUES
        (1, 'Z363700Z01', '100')
    ,   (2, 'Z363700Z01', '200')
    ,   (3, '0119-960-1', '200')
    ,   (4, '445-3-1234', '100')