2016-07-26 6 views
3

Ich muss Daten von einer Spalte auf 10 Zeichen abschneiden. Ich kann jedoch keine Duplikate haben, daher möchte ich, dass Duplikate mit ~ 1 für das erste Duplikat, ~ 2 für das zweite Duplikat enden. Hier ist ein Beispiel dafür, was ich habe:T-SQL Kürzen Sie Text und fügen Sie am Ende eine Zahl hinzu, um Duplikate zu vermeiden.

Column 
------ 
The ABC Company Inc. 
The ABC Cooperative 
XYZ Associates LLC. 

ich das Ergebnis sein möchte:

Column 
------ 
The ABC ~1 
The ABC ~2 
XYZ Associ 

Das Ende nicht sein muss ~ 1 oder ~ 2, ich brauche nur etwas zu mache es nach dem Abschneiden einzigartig. Es kann mehr als 3 oder 4 Duplikate nach dem Abschneiden geben.

Bisher bin ich nur Kürzen und Bearbeiten der Tabelle manuell:

update Table set Column = Left(Column, 10) where len(Column) > 10 
+0

Wenn Sie "The ABC Company Inc." gestutzt und "The ABC Cooperative" auf 10 Zeichen, bleibt für beide das "The ABC Co" übrig, was zu einem Duplikat führt. – Peter

+1

Das ABC ~ 1 IS 10 Zeichen – AntDC

+2

Was ist, wenn es 10 oder mehr Duplikate gibt? – datagod

Antwort

4

Zuerst Sie über die ersten 8 Zeichen kümmern, nicht die ersten 10 , weil Sie für die zusätzliche Nummer Plätze reservieren müssen.

Unter der Annahme, dass Sie weniger als 10 Wiederholungen haben, können Sie dies tun:

with toupdate as (
     select t.*, 
      row_number() over (partition by left(col, 8) order by (select null)) as seqnum, 
      count(*) over (partition by left(col, 8)) as cnt 
     from t 
update toupdate 
    set col = (case when cnt = 1 then left(col, 10) 
        else left(col, 8) + '~' + cast(seqnum as char(1)); 

Die gleiche Idee kann für eine select verwendet werden.

+1

Es ist erwähnenswert, dass die Nummerierung nicht garantiert wird, um stabil zu sein und dass, wenn Zeilen hinzugefügt oder gelöscht werden, die Nummerierung aller Wahrscheinlichkeit nach ändern wird. Das macht es nicht falsch, aber es könnte das OP zu einem späteren Zeitpunkt überraschen. – HABO

+0

Das sieht aus wie ich brauche. Ich versuche, die Abfrage zu ändern, aber ich habe Probleme mit der ersten Zeile "mit toupdate as". Kann ich diesem Code noch etwas hinzufügen? Ich habe "toupdate" durch den Tisch ersetzt, den ich aktualisieren wollte. SQL Management Studio sagt, es gibt einen Syntaxfehler in der Nähe von 'von t' nicht sicher, wie Sie das beheben ... – Peter

+1

@Peter. . . Die Tabelle geht in die 'from'-Klausel zwischen' from' und 't'. –

4
Declare @Table Table (Column1 varchar(50)) 
Insert into @Table values 
('The ABC Company Inc.'), 
('The ABC Cooperative'), 
('XYZ Associates LLC.') 

Select NewColumn = Concat(substring(Column1,1,10),' ~',Row_Number() over (Partition By substring(Column1,1,10) Order by Column1)) 
From @Table 

Returns

NewColumn 
The ABC Co ~1 
The ABC Co ~2 
XYZ Associ ~1 
+0

Wie Gordon erwähnt, könnte die 10 sein 8 –

1

Die Zahlen sind laut, so dass ich sie nur hinzufügen, wenn nötig:

select case when _r > 1 
    then Company + '~' + cast(_r as varchar(5)) 
    else Company end as Company 
from (
    select Company 
     , ROW_NUMBER() over (partition by Company order by Company) as _r 
    from(
     select left(Company, 10) as Company 
     from MyTable 
    ) x 
) y 
order by Company 


Company 
-------------- 
The ABC Co 
The ABC Co~2 
XYZ Associ 
+0

Ich mag diese Lösung, aber wie verwende ich diese, um meine vorhandene Tabelle zu aktualisieren? Ich kann dieser Datenbank keine neuen Tabellen hinzufügen, die Art der Abfrage hilft, aber ich muss die Tabelle weiterhin aktualisieren. – Peter

0

Angenommen, Ihre Tabelle COMPANY ist und das Feld ist Company ..... Sie werden tweek müssen aber hoffen, dass es hilft ..

SELECT SUBSTRING(Q.Comp, 1, 5) + '~' + CONVERT(nvarchar(4), Row) as NewFieldValue FROM 
(
SELECT ROW_NUMBER() OVER(PARTITION BY SUBSTRING(C.CompanyName, 1, 6) ORDER BY SUBSTRING(C.CompanyName, 1, 6)) AS Row, 
SUBSTRING(C.CompanyName, 1, 6) as Comp 
FROM COMPANY C 
)Q 
0
DECLARE @Table TABLE (Column1 varchar(50)) 

INSERT INTO @Table VALUES 
     ('The ABC Company Inc.') 
    , ('The ABC Cooperative') 
    , ('XYZ Associates LLC.') 
    , ('Acme') 
    , ('Ten Char 123') 
    , ('Ten Char 132') 
    , ('Ten Char 231') 


;WITH FLen 
    AS (
     SELECT Column1, LEFT(LEFT(Column1,13) + SPACE(13),13) + CHAR(164) AS Column2 
      FROM @Table 
     ) 

,TenCharPD -- Includes possible duplicates 
    AS (
     SELECT Column1, LEFT(Column2,8) + 
      RIGHT('0' + CAST (
      (ASCII(SUBSTRING(Column2, 9,1)) + 
      ASCII(SUBSTRING(Column2,10,1)) + 
      ASCII(SUBSTRING(Column2,11,1)) + 
      ASCII(SUBSTRING(Column2,12,1)) + 
      ASCII(SUBSTRING(Column2,13,1)))%100 
      AS NVARCHAR(2)),2) AS Column2 
     FROM Flen 
     ) 
,CullPD 
    AS (
     SELECT Column1, Column2, 
      ROW_NUMBER() OVER (PARTITION BY Column2 ORDER BY Column2) AS rowx 
     FROM TenCharPD 
     ) 

UPDATE t1 
    SET Column1 = LEFT(Column2,9) + 
    CASE rowx 
     WHEN 1 THEN RIGHT(Column2,1) 
     ELSE CHAR(rowx + CAST (RIGHT(Column2,1) AS INT) * 5 + 63) 
     END 
    FROM @Table t1 
     JOIN CullPD cpd 
      ON t1.Column1 = cpd.Column1 

SELECT * FROM @Table 
+0

Gibt es eine Möglichkeit für mich, diesen Code zu verwenden, um meine vorhandene Tabelle im laufenden Betrieb zu aktualisieren? – Peter

+0

Wie möchten Sie die Werte in Spalte1 durch die von Spalte2 ersetzen? – DaveX

+0

Ja bitte.Die Abfrage ist gut, aber ich brauche etwas, um auch die Spalten zu aktualisieren, danke! – Peter

Verwandte Themen