2016-07-26 1 views
3

Мне нужно обрезать данные из столбца до 10 символов. Однако у меня не может быть дубликатов, поэтому я хочу, чтобы любые дубликаты заканчивались на ~ 1 для первого дубликата, ~ 2 для второго дубликата. Вот пример того, что у меня есть:T-SQL Усечь текст и добавить номер в конце, чтобы избежать дублирования

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

Я хотел бы результат быть:

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

Конец не должен быть ~ 1 или ~ 2, мне просто нужно что-то сделать его уникальным после усечения. После усечения может быть больше 3 или 4 дубликатов.

До сих пор, я просто усечения и редактирования таблицы вручную:

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

Если вы усечение "АЗБУКА Company Inc." и «ABC Cooperative» до 10 символов, вы останетесь с «The ABC Co» для обоих, что приведет к дублированию. – Peter

+1

ABC ~ 1 IS 10 символов – AntDC

+2

Что делать, если есть 10 или более дубликатов? – datagod

ответ

4

Во-первых, вы заботитесь о первых 8 символов, а не первые 10 , потому что вам нужно зарезервировать слоты для дополнительного номера.

Если предположить, что у вас меньше 10 повторений, вы можете сделать это:

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)); 

Та же идея может быть использована для select.

+1

Стоит отметить, что нумерация не гарантируется стабильной и что если строки будут добавлены или удалены, нумерация, по всей вероятности, изменится. Это не делает это неправильно, но это может удивить OP в более поздний срок. – HABO

+0

Это похоже на то, что мне нужно. Я пытаюсь изменить запрос, но у меня возникают проблемы с первой строкой 'with toupdate as'. Могу ли я добавить что-нибудь еще к этому коду? Я заменил 'toupdate' таблицей, которую я хотел обновить. SQL Management Studio говорит, что есть синтаксическая ошибка рядом с «от t' и не уверен, как исправить это ... – Peter

+1

@Peter. , , Таблица находится в разделе 'from' между' from' и '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 

Возвращает

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

Как упоминал Гордон, 10 может быть 8 –

1

Номера шумные, так что я только добавить их, когда это необходимо:

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

Мне нравится это решение, но как его использовать для обновления существующей таблицы? Я не могу добавить новые таблицы в эту базу данных, тип запросов помогает, но мне все равно нужно обновлять таблицу «на лету». – Peter

0

Предполагая, что ваша таблица COMPANY и поле CompanyName ..... Вам придется Твик, но надеюсь, что это помогает ..

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

Есть ли способ использовать этот код для обновления существующей таблицы на лету? – Peter

+0

As-in, вы хотите заменить значения в столбце 1 на столбцы Column2? – DaveX

+0

Да, пожалуйста.Получение запроса является хорошим, но мне нужно что-то, чтобы также обновить столбцы, спасибо! – Peter

Смежные вопросы