我正在与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
计算每个具有count> 1的截断名称的全名数量)以及while循环,将截断的全名存储在变量中,但是这超出了我的能力。
我想进入一个像这样的表(在更新第二和第四行的全名之后):
|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 |
答案 0 :(得分:1)
您可以使用以下解决方案:
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
。该解决方案在FullName
列处以相同的开头连接记录。使用LEN(t2.FullName) > LEN(t1.FullName)
,您可以排除找到的FullName
小于或等于当前FullName
的长度的所有记录。
答案 1 :(得分:1)
运行第一个查询,看看是否能满足您期望的结果。第二个查询将是您的更新。
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
答案 2 :(得分:0)
您可以进行自我连接,将中间结果放入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
答案 3 :(得分:0)
使用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
答案 4 :(得分:0)
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