заменить укороченные строки в некоторых записях полными строками из других записей - PullRequest
0 голосов
/ 25 июня 2019

Я работаю с MS SQL Server 2014.

У меня есть набор данных с названиями компаний, которые иногда усекаются из-за нехватки места в источнике.E.g. AAA PTY Ltd иногда отображается как 'AAA PTY L', а иногда как исходное неусеченное имя, в зависимости от источника.Мне нужно заменить усеченные значения на длинные, где они усечены, чтобы избежать дублирования записей при сопоставлении с другими наборами данных.Заменить полные имена на усеченные легко, но мне нужно наоборот.

Я создал таблицу с длинными и усеченными именами, упорядочил ее по убыванию (чтобы длинные имена всегда появлялись перед усеченными) и добавил столбец для усеченных имен (имитирует усечение, где полное имяне было усечено).Я также создал флаг, чтобы указать, был ли он усечен, чтобы я мог легко идентифицировать записи, которые мне нужно обновить.Поэтому созданная мной таблица выглядит следующим образом:

|Id | FullName     | Truncated name | TruncFlag|
|1  | AAA PTY Ltd  | AAA PTY L      | 1        |
|2  | AAA PTY L    | AAA PTY L      | 0        |
|3  | BBB PTY Ltd  | BBB PTY L      | 1        |
|4  | BBB PTY L    | BBB PTY L      | 0        |

Мне нужно заменить полное имя во второй и четвертой строках на полное имя в первой и третьей строках соответственно.

Я пытался сделать это с помощью JOINS (subqeries, считая количество полных имен на усеченное имя, имеющее счет> 1), а также с помощью циклов while, сохраняя усеченные и полные имена в переменных, но этовне моих возможностей.

Я бы хотел получить таблицу вроде (после обновления FullNames во второй и четвертой строках):

|Id | FullName     | Truncated name | TruncFlag|
|1  | AAA PTY Ltd  | AAA PTY L      | 1        |
|2  | AAA PTY Ltd  | AAA PTY L      | 0        |
|3  | BBB PTY Ltd  | BBB PTY L      | 1        |
|4  | BBB PTY Ltd  | BBB PTY L      | 0        |

Ответы [ 5 ]

1 голос
/ 25 июня 2019

Запустите первый запрос и посмотрите, сработает ли это для ожидаемых результатов. Второй запрос будет вашим обновлением.

select t.fullname, 'will change to', l.fullname 
set t.fullname = l.fullname
from yourtable l
join yourtable t on l.truncatedname = t.truncatedname
where l.truncflag = 1
and t.truncflag=0

update t
set t.fullname = l.fullname
from yourtable l
join yourtable t on l.truncatedname = t.truncatedname
where l.truncflag = 1
and t.truncflag=0
1 голос
/ 25 июня 2019

Вы можете использовать следующее решение:

UPDATE t1 SET t1.FullName = t2.FullName
FROM table_name t1 INNER JOIN table_name t2 ON t2.FullName LIKE t1.FullName + '%' 
    AND LEN(t2.FullName) > LEN(t1.FullName)

Это решение не использует столбцы TruncFlag и TruncatedName для получения FullName.Вы можете получить FullName из других записей.Решение объединяет записи с одинаковым началом в столбце FullNameLEN(t2.FullName) > LEN(t1.FullName) вы исключаете все записи, в которых найденная FullName меньше или равна длине текущей (возможно, усеченной) FullName.

демо на dbfiddle.uk

0 голосов
/ 25 июня 2019
UPDATE t1
SET t1.FullName = t2.FullName
FROM Truncated_table t1
OUTER APPLY (
    SELECT FullName
    FROM Truncated_table
    WHERE [Truncated name] = t1.[Truncated name]
        AND TruncFlag = 1
    ) AS t2
WHERE TruncFlag = 0
0 голосов
/ 25 июня 2019

Решение с EXISTS без использования флага усечения.

;WITH ToUpdate AS
(
    SELECT
        T.Id,
        T.FullName,
        NewFullName = T.FullName + 'td'
    FROM
        YourTable AS T
    WHERE
        T.FullName LIKE '%L' AND
        EXISTS (
            SELECT
                'at least one full name matches with Ltd'
            FROM
                YourTable AS F
            WHERE
                F.FullName = T.FullName + 'td')
)
UPDATE T SET
    FullName = NewFullName
FROM
    ToUpdate AS T
0 голосов
/ 25 июня 2019

Вы можете выполнить самостоятельное объединение, поместить промежуточные результаты в CTE и запустить обновление. Этот пример работает для ваших ограниченных данных. Если существуют крайние случаи, когда усеченное значение выглядит так же, как другое усеченное значение, но полное имя отличается между ними, это вызовет проблемы.

;with CTE AS (
SELECT 
t1.ID, 
t1.fullname AS fullname_actual, 
t2.fullname AS fullname_truncated

FROM your_table t1
INNER JOIN your_table t2
    ON t1.truncatedname = t2.truncatedname
    AND t1.fullname <> t2.fullname
    AND t1.truncflag = 1
    AND t2.truncflag = 0

)
UPDATE your_table 
SET fullname = fullname_actual
FROM cte 
WHERE fullname_truncated = fullname
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...