我正在寻找一种优雅的方式来重新格式化数据以进行连接。我有两个表具有相同的密钥数据,但格式有很大不同。
我正在使用SQL Server。数据看起来像这样 表1:
74-123-58
896-777-92
4567-78
表2:
00007400123
00089600777
00456700078
表1将密钥分为按破折号分隔的元素,第3个元素(表2中未找到)有时会丢失。
表2总是将第一个元素左边的零填充为6个字符,第二个元素左边的零填充为5个字符。
我可以使用由嵌入式charindex,left,substring和replicate函数组成的非常长的公式来实现这一点。我想用一些简单的东西来编写它,并且对于那些试图在将来对我的代码进行故障排除的人来说更容易理解。
有什么好主意吗?
答案 0 :(得分:1)
这些看起来都像字符串,因此请使用like
。你需要做一些字符串修改,但我认为这有效:
select . . .
from t1 join
t2
on t1.key like cast(left(t2.key, 6) + 0 as varchar(255)) + '-' +
cast(right(t2.key, 5) + 0 as varchar(255)) + '%';
但是,您应该在数据中解决此问题。
注意:上面有一个问题,因为第二个键可能是1,它将匹配100.这可以通过确保后面的连字符来解决。但是,我们需要注意两部分键:
select . . .
from t1 join
t2
on t1.key + '-' like cast(left(t2.key, 6) + 0 as varchar(255)) + '-' +
cast(right(t2.key, 4) + 0 as varchar(255)) + '-%';
我强烈建议您为每个创建标准化格式的表添加计算列。然后,您可以在计算列上创建索引,甚至可以为此类查询获得一点性能。
答案 1 :(得分:0)
这些是其他一些方法。
SELECT *
FROM Table1 t1
JOIN Table2 t2 on REPLACE(t1.value1,'-','')
LIKE cast(left(t2.value2, 6)+ 0 as varchar(255))
+ cast(right(t2.value2, 5) + 0 as varchar(255))+'%'
OR
SELECT *
FROM Table1 t1
JOIN Table2 t2 on REPLACE(t1.value1,'-','')
LIKE REPLACE(LTRIM(REPLACE(left(t2.value2, 6), '0', ' ')),' ', '0')
+ REPLACE(LTRIM(REPLACE(right(t2.value2, 5), '0', ' ')),' ', '0')+'%'
答案 2 :(得分:0)
根据您想去的方向,我看到两个选项:
on t2.[key] =
right(
'000000' +
left(
t1.[key],
charindex('-', t1.[key]) - 1
),
6
) +
right(
'00000' +
substring(t1.[key],
charindex('-', t1.[key]) + 1,
charindex('-', t1.[key] + '-', charindex('-', t1.[key]) + 1) -
charindex('-', t1.[key]) - 1
),
5
)
和
on t1.[key] + '-' like
cast(cast(substring(t2.[key], 1, 6) as int) as varchar(6)) + '-' +
cast(cast(substring(t2.[key], 7, 5) as int) as varchar(5)) + '-' + '%'
如果您的SQL Server版本为format()
,则可以使用该版本而不是right('000000' + X, 6)
方法。