2016-09-15 16 views
1

私は完全にカーソルベースのセットからセットベースにコードを移動しています。これは私の頭の中で行われています。挿入された各社に6文字のショートコードデータベースと私は(カーソル)の外側でこれを達成するために(私が望む)。私はこれまでで午前どこのユニークな識別子をセットベースのクエリとして生成

例:

CREATE TABLE #customers (name VARCHAR(50), shortname VARCHAR(10)) 
INSERT INTO #customers VALUES 
('Michael Smith', 'Michae') 
,('Michael Douglas', 'Mich_1') 
,('Michael Yang', 'Mich_2') 

CREATE TABLE #newcustomers (name VARCHAR(50), shortname VARCHAR(10) NULL) 
INSERT INTO #newcustomers (name) VALUES 
('Michael Black') 
,('Michael White') 

SELECT * FROM #customers 
SELECT * FROM #newcustomers 

DECLARE @shortname VARCHAR(10) 
DECLARE @iteration INT = 0 

WHILE EXISTS(SELECT shortname FROM #customers WHERE shortname = @shortname) 
BEGIN 
    SELECT @shortname = LEFT(name, 6) FROM #newcustomers 

    UPDATE #newcustomers SET shortname = @shortname 

    SET @shortname = LEFT(@shortname, 4) + '_' + @iteration 

    SET @iteration = @iteration + 1 
END 

がうまくいけば、例では、私が取得しようとしています場合は、任意の提案や例は非常に参考になる特定するのに十分です。私の例はうまくいきません。

+1

を取得し、6文字を取得しますカーソルとして実行されます。それは同じ実装を使用するつもりです。ちょうど 'WHILE'としてマスクされています。 –

+0

'Micahel Douglas'にタイプミスがあります... – Shnugo

+0

Btw:これは良い質問です。特にcopy'n'Pasteableテストシナリオは素晴らしい、自分の努力、明確な説明です... +1 – Shnugo

答えて

2

モックアップ

CREATE TABLE #customers (ID INT IDENTITY, name VARCHAR(50), shortname VARCHAR(10)) 
INSERT INTO #customers VALUES 
('Michael Smith', 'Michae') 
,('Michael Douglas', 'Mich_1') 
,('Michael Yang', 'Mich_3') 
,('Testman', 'Testma') 
,('Testman1', 'Test_1'); 

CREATE TABLE #newcustomers (ID INT IDENTITY,name VARCHAR(50), shortname VARCHAR(10) NULL) 
INSERT INTO #newcustomers (name) VALUES 
('Michael Black') 
,('Michael White') 
,('Testman2') 
,('Someone new'); 

- このCTEは、すべての既存の名前を結合しますよう

WITH AllNames AS 
(
    SELECT '1_old' AS datasource,ID,name,shortname FROM #customers 
    UNION ALL SELECT '2_new',ID,name,shortname FROM #newcustomers 
) 

- このCTEを組み合わせリストを使用します。この

あなたのテーブルをお試しください正しい「指標」を計算する

= 1 NrTotalで新しい--All 10

あるとして、他の全てのちょうどノートとして、 `WHILE`も意志インデックス

SELECT * 
     ,CASE WHEN datasource='1_old' THEN shortname ELSE 
     CASE WHEN datasource='2_new' AND NrTotal=1 THEN First6 
      ELSE LEFT(First6,4) + '_' + CAST(Nr + (SELECT ISNULL(MAX(x.ExistIndex),1) 
                 FROM ShortNames AS x 
                 WHERE x.First6=ShortNames.First6) AS VARCHAR(5)) 
     END 
     END 
FROM ShortNames 

GO 
DROP TABLE #customers; 
DROP TABLE #newcustomers; 

結果

+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+ 
| datasource | ID | name   | shortname | First6 | NrTotal | Nr | ExistIndex | (Kein Spaltenname) | 
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+ 
| 1_old  | 1 | Michael Smith | Michae | Michae | 1  | 1 | 0   | Michae    | 
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+ 
| 1_old  | 2 | Michael Douglas | Mich_1 | Michae | 2  | 2 | 1   | Mich_1    | 
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+ 
| 1_old  | 3 | Michael Yang | Mich_3 | Michae | 3  | 3 | 3   | Mich_3    | 
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+ 
| 1_old  | 4 | Testman   | Testma | Testma | 1  | 1 | 0   | Testma    | 
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+ 
| 1_old  | 5 | Testman1  | Test_1 | Testma | 2  | 2 | 1   | Test_1    | 
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+ 
| 2_new  | 1 | Michael Black | NULL  | Michae | 4  | 1 | 0   | Mich_4    | 
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+ 
| 2_new  | 2 | Michael White | NULL  | Michae | 5  | 2 | 0   | Mich_5    | 
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+ 
| 2_new  | 4 | Someone new  | NULL  | Someon | 1  | 1 | 0   | Someon    | 
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+ 
| 2_new  | 3 | Testman2  | NULL  | Testma | 3  | 1 | 0   | Test_2    | 
+------------+----+-----------------+-----------+--------+---------+----+------------+--------------------+ 
+0

これは驚くほどのことです!私は畏敬の念を抱いています!これが考慮されない唯一の事は、たとえば「Mich_2」(マイケル・ヤンを「Mich_3」に変更する)が行方不明で、これを実行すると、ROW_NUMBERの実行中に重複が存在することです。実際には、実行されるたびに番号を再発行することで、元のインクリメントを完全に無視します。 –

+0

@BrianRamsey、私の更新を参照してください – Shnugo

+0

驚くべきこと...言葉無し...私は実際に元のコードで同じことを達成しようとしていました。あなたが持っているほど速く。私はあなたの努力に十分な感謝を送ることができません。ありがとうございました! –

0

1つのオプションは、computed columnを使用することです。これらの線に沿って

表のデザインは機能するであろう:

- Sample table. 
DECLARE @Sample TABLE 
    (
     Id   INT IDENTITY(1, 1), 
     FullName VARCHAR(255), 
     ShortName AS LEFT(FullName, 4) + '_' + CAST(Id AS VARCHAR(255)) 
    ) 
; 

-- Add set containing two companies. 
INSERT INTO @Sample 
    (
     FullName 
    ) 
VALUES 
    ('ABC LTD'), 
    ('XYZ PLC') 
; 

戻り

Id FullName ShortName 
1 ABC LTD  ABC _1 
2 XYZ PLC  XYZ _1 

IdShortName列はSQL Serverによって管理されます。 FullNameを追加するだけです。それが簡単に一緒に演奏できるようにすること、テーブル変数を使用して

EDIT

再加工例。

+0

という価値があります。 'ABC _1、XYZ _2'を実行すると、現在のシステムの振る舞いのために、それらを' ABC _1、XYZ _1'にする必要があります。また、現在の行動のために、最初のエントリは常にLEFT 6でなければなりません。 –

+0

ああそうです。 @RaduGheorghiuソリューションと[ウィンドウ行数](https://msdn.microsoft.com/en-GB/library/ms186734.aspx?f=255&MSPPError=-2147217396)を組み合わせることができます。 –

関連する問題