2015-05-19 90 views
2

我正在將數據從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

您能否提供一些示例數據?我想一些應用程序。RecieiptId和imp.Ref就足夠了。另外,應該認爲'A1234'等於'A12345'嗎? –

+0

@ZoharPeled不,每個ReceiptId都是唯一的。我會添加一些示例數據,但我認爲這是相當好的描述。 – Adeptus

+0

我會建議不要在執行連接時專門在sql中執行此操作。 – ughai

回答

1

由於ughaihis comment理所當然地寫道,這不是建議joinon子句中使用任何其他然後列。
原因是使用函數可防止sql server在沒有函數的情況下使用它的列上的任何索引。

因此,我會建議在imp表中添加另一列,以保留實際的ReceiptId並在導入過程中自行計算。

我覺得從ref列提取ReceiptId的最佳方法是使用substringpatindex,這表現在this fiddle

SELECT ref, 
     RTRIM(SUBSTRING(ref, PATINDEX('%A[0-9][0-9][0-9][0-9]%', ref), 6)) As ReceiptId 
FROM imp 

更新
與T-克勞森-DK在談話後評論,我想出了這個:

SELECT ref, 
     CASE WHEN PATINDEX('%[ ]A[0-9][0-9][0-9][0-9][0-9| ]%', ref) > 0 
     OR PATINDEX('A[0-9][0-9][0-9][0-9][0-9| ]%', ref) = 1 THEN 
      SUBSTRING(ref, PATINDEX('%A[0-9][0-9][0-9][0-9][0-9| ]%', ref), 6) 
     ELSE 
      NULL 
     END As ReceiptId 
FROM imp 

fiddle here

這將返回空值,如果不存在匹配, 當匹配是包含A,接着爲4或5位,從字符串的其餘部分由空格分隔的子串,並且可以在開始時被發現,字符串的中間或結尾。

+0

如果varchar爲'A1234A',則它仍將被視爲有效。如果你的varchar沒有包含有效數據,它會比較第一個字符,你的RTRIM也是不必要的, –

+0

如果varchar沒有包含有效數據,那麼比較應該會失敗,但是感謝rtrim建議和最後一個空間,我會編輯我的答案來解決這個問題。 –

+0

如果varchar(REF)以6個空格開始並且無效,那麼一旦您比較並且ReceiptId中有很多空的變體,您將全部更新它們 –

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

當使用相等,間隔後未評估

+0

[我看到你的'patindex'和我一樣大......: - ]](http://www.imdb.com/title/tt0094012/quotes?item=qt0467008) –

相關問題