我有一个带有contract_code列的表,但是在这个列中有相同的数据,我怎样才能将相同的数据更改为samedata_a和samedata_b等。
例如:更改此数据
阿斯弗雷特 JDFJDSFJS 阿斯弗雷特
到
ASFRETERT_a JDFJDSFJS ASFRETERT_b
我有一个带有contract_code列的表,但是在这个列中有相同的数据,我怎样才能将相同的数据更改为samedata_a和samedata_b等。
例如:更改此数据
阿斯弗雷特 JDFJDSFJS 阿斯弗雷特
到
ASFRETERT_a JDFJDSFJS ASFRETERT_b
您可以通过将 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