0

我有一个带有contract_code列的表,但是在这个列中有相同的数据,我怎样才能将相同的数据更改为samedata_a和samedata_b等。

例如:更改此数据

阿斯弗雷特
JDFJDSFJS
阿斯弗雷特

ASFRETERT_a
JDFJDSFJS
ASFRETERT_b
4

1 回答 1

3

您可以通过将 arow_number()应用于列来执行此操作。如果您不需要将附加字符作为alpha字符,那么使用以下内容会更容易:

使用 CTE 的第一个版本:

-- cte version
;with cte as
(
  select col1, row_number() over(partition by col1 order by col1) rn
  from yourtable
)
select 
  case when t1.cnt > 1 
      then c.col1 + '_' 
        + cast(c.rn as varchar(10))
      else c.col1
  end yourColumn
from cte c
inner join
(
  select count(*) cnt, col1
  from yourtable
  group by col1
) t1
  on c.col1 = t1.col1;

第二个版本使用子查询

-- non-cte version
select case when t2.cnt > 1 
      then t1.col1 + '_' 
          + cast(t1.rn as varchar(10))
      else t1.col1 
  end yourColumn
from 
(
  select col1, row_number() over(partition by col1 order by col1) rn
  from yourtable
) t1
inner join
(
  select count(*) cnt, col1
  from yourtable
  group by col1
) t2
  on t1.col1 = t2.col1

请参阅SQL Fiddle with Demo。上面的两个版本在列的末尾添加了一个整数,但如果你想应用一个字母字符,你应该在你的数据库中添加一个函数(来自StackOverflow上这个问题的函数代码):

CREATE FUNCTION dbo.fnColumnNameFromIndex(@i int)
RETURNS varchar(3)
AS
BEGIN
DECLARE @dividend int, @letters varchar(3), @modulo int
    SET @dividend = @i
    SET @letters = ''

    WHILE @dividend > 0
    BEGIN
        SET @modulo = (@dividend - 1) % 26
        SET @letters = CHAR(65 + @modulo) + @letters
        SET @dividend = CONVERT(int, (@dividend - @modulo) / 26 )
    END

    RETURN @letters
END

如果创建此函数,则可以获取每行的字母字符。您的查询将是:

CTE 版本:

-- cte version
;with cte as
(
  select col1, row_number() over(partition by col1 order by col1) rn
  from yourtable
)
select 
  case when t1.cnt > 1 
      then c.col1 + '_' 
        + cast(dbo.fnColumnNameFromIndex(c.rn) as varchar(10))
      else c.col1
  end yourColumn
from cte c
inner join
(
  select count(*) cnt, col1
  from yourtable
  group by col1
) t1
  on c.col1 = t1.col1;

子查询版本:

-- non-cte version
select case when t2.cnt > 1 
      then t1.col1 + '_' 
          + cast(dbo.fnColumnNameFromIndex(t1.rn) as varchar(10))
      else t1.col1 
  end yourColumn
from 
(
  select col1, row_number() over(partition by col1 order by col1) rn
  from yourtable
) t1
inner join
(
  select count(*) cnt, col1
  from yourtable
  group by col1
) t2
  on t1.col1 = t2.col1

请参阅带有演示的 SQL Fiddle

于 2012-09-28T12:47:49.837 回答