代码之家  ›  专栏  ›  技术社区  ›  Megrez7

通过附加数字将重复值转换为非重复值

  •  2
  • Megrez7  · 技术社区  · 6 年前

    我的数据库不区分大小写,但导入的数据来自外部区分大小写的系统。唯一索引由3列组成,但由于区分大小写问题,所有3列不再唯一。

    例子:

    +------+------+------+
    | Col1 | Col2 | Col3 |
    +------+------+------+
    |    1 |    2 | abc  |
    |    1 |    2 | aBc  |
    |    1 |    2 | ABC  |
    |    1 |    3 | abc  |
    |    2 |    4 | abc  |
    +------+------+------+
    

    我希望只向列3中的值追加一个数字,这将导致基于所有3列重复的索引。这与在特定的“ABC”版本中附加的数字无关。预期结果:

    +------+------+------+
    | Col1 | Col2 | Col3 |
    +------+------+------+
    |    1 |    2 | abc1 |
    |    1 |    2 | aBc2 |
    |    1 |    2 | ABC3 |
    |    1 |    3 | abc  |
    |    2 |    4 | abc  |
    +------+------+------+
    

    两种解决方案都可以接受:更新源表或“即时”选择。

    我在本地使用SQL Server 2017,在生产中使用Azure SQL。

    1 回复  |  直到 6 年前
        1
  •  6
  •   Gordon Linoff    6 年前

    你可以用 row_number() . 以下假定排序规则不区分大小写(默认)

    select t.col1, t.col2,
           (case when count(*) over (partition by col1, col2, col3) = 1
                 then col1
                 else col3 + convert(varchar(255), row_number() over (partition by col1, col2, col3 order by col1) )
            end) as new_col3
    from t;
    

    您可以轻松地将其转换为更新:

    with toupdate as (
          select t.*,
                 (case when count(*) over (partition by col1, col2, col3) = 1
                       then col1
                       else col3 + convert(varchar(255), row_number() over (partition by col1, col2, col3 order by col1) )
                  end) as new_col3
          from t
         )
    update toupdate
        set col3 = new_col3
        where new_col3 <> col3;
    

    您可以使用 COLLATE ,如果不是默认值。