我正在从Excel电子表格中将数据导入我的SQL数据库。
imp
表是导入的数据,app
表是现有的数据库表。
app.ReceiptId
的格式为" A"接着是一些数字。以前它是4位数,但现在可能是4位或5位数。
示例:
A1234
A9876
A10001
imp.ref
是Excel中的自由文本引用字段。它由一些任意长度的描述组成,然后是ReceiptId,后跟一个格式为"的无关参考号。 - BZ-0987654321" (有时裁短,甚至完全丢失)。
示例:
SHORT DESC A1234 - BZ-0987654321
LONGER DESCRIPTION A9876 - BZ-123
REALLY LONG DESCRIPTION A2345 - B
REALLY REALLY LONG DESCRIPTION A23456
以下代码适用于4位ReceiptId
,但无法正确捕获5位数字。
UPDATE app
SET
[...]
FROM imp
INNER JOIN app
ON app.ReceiptId = right(right(rtrim(replace(replace(imp.ref,'-',''),'B','')),5)
+ rtrim(left(imp.ref,charindex(' - BZ-',imp.ref))),5)
如何更改代码以便捕获4(A1234)或5(A12345)数字?
答案 0 :(得分:1)
正如ughai在his comment中正确写的那样,不建议在on
的{{1}}子句中使用除列之外的任何内容。
原因是使用函数会阻止sql server在没有函数的情况下使用它可能使用的列上的任何索引。
因此,我建议在imp表中添加另一个列,该列将保存实际的join
并在导入过程中自行计算。
我认为从ReceiptId
列中提取ReceiptId
的最佳方法是将substring
与patindex
一起使用,如this fiddle中所示:
ref
<强>更新强>
在评论中与t-clausen-dk对话后,我想出了这个:
SELECT ref,
RTRIM(SUBSTRING(ref, PATINDEX('%A[0-9][0-9][0-9][0-9]%', ref), 6)) As ReceiptId
FROM imp
如果没有匹配,则返回null, 当匹配是包含A后跟4或5位数的子字符串时,用字符串的其余部分用空格分隔,并且可以在字符串的开头,中间或末尾找到。
答案 1 :(得分:1)
试试这个,它将删除A [编号] [编号] [编号] [编号]之前的所有字符,然后取出前6个字符:
UPDATE app
SET
[...]
FROM imp
INNER JOIN app
ON app.ReceiptId in
(
left(stuff(ref,1, patindex('%A[0-9][0-9][0-9][0-9][ ]%', imp.ref + ' ') - 1, ''), 5),
left(stuff(ref,1, patindex('%A[0-9][0-9][0-9][0-9][0-9][ ]%', imp.ref + ' ') - 1, ''), 6)
)
当使用相等时,不评估后面的空格