0

contract_code 列を含むテーブルがありますが、この列には同じデータがあります。同じデータを samedata_a や samedata_b などに変更するにはどうすればよいですか?

例: このデータを変更します。

ASFRETERT
JDFJDSFJS
ASFRETERT

ASFRETERT_a
JDFJDSFJS
ASFRETERT_b
4

1 に答える 1

3

これを実行する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 を参照してください

于 2012-09-28T12:47:49.837 に答える