将a,b,c添加到数据末尾

时间:2012-09-28 10:27:44

标签: tsql

我有带contract_code列的表,但是在此列中有相同的数据,如何将相同的数据更改为samedata_a和samedata_b等。

例如: 更改此数据

ASFRETERT
JDFJDSFJS
ASFRETERT

ASFRETERT_a
JDFJDSFJS
ASFRETERT_b

1 个答案:

答案 0 :(得分:3)

您可以通过将row_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 with Demo

相关问题