contract_code 列を含むテーブルがありますが、この列には同じデータがあります。同じデータを samedata_a や samedata_b などに変更するにはどうすればよいですか?
例: このデータを変更します。
ASFRETERT JDFJDSFJS ASFRETERT
に
ASFRETERT_a JDFJDSFJS ASFRETERT_b
contract_code 列を含むテーブルがありますが、この列には同じデータがあります。同じデータを samedata_a や samedata_b などに変更するにはどうすればよいですか?
例: このデータを変更します。
ASFRETERT JDFJDSFJS ASFRETERT
に
ASFRETERT_a JDFJDSFJS ASFRETERT_b
これを実行するrow_number()
には、列に a を適用します。追加の文字を文字にする必要がない場合は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;
2 番目のバージョンでは、サブクエリを使用します
-- 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を参照してください。上記の 2 つのバージョンでは、列の末尾に整数が追加されますが、アルファベット文字を適用する場合は、データベースに関数を追加する必要があります ( 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 を参照してください