2017-09-29 72 views
1

這是SELECT語句的一部分。邏輯非常簡單,但我覺得有必要縮短第3和第4行。相當短的SQL語句,但有很多'SUBSTRING'語句,這可以更好地優化嗎?

'TR.xType'字符串最有可能看起來像「Users | true | null」。第3行和第4行正在檢查在這種情況下,中間值「true」在使用之前是否是有效的布爾值。

CASE WHEN PD.DisplayModeRestricted = 1 
THEN ISNULL(PD.DisplayOpenMode, 1) 
ELSE CASE WHEN LOWER(SUBSTRING(TR.xType, CHARINDEX('|', TR.xType, 0) + 1, CHARINDEX('|', TR.xType, CHARINDEX('|', TR.xType, 0) + 1) - CHARINDEX('|', TR.xType, 0) - 1)) IN ('true', 'false') 
    THEN LOWER(SUBSTRING(TR.xType, CHARINDEX('|', TR.xType, 0) + 1, CHARINDEX('|', TR.xType, CHARINDEX('|', TR.xType, 0) + 1) - CHARINDEX('|', TR.xType, 0) - 1)) 
    ELSE ISNULL(@displayOpenMode, ISNULL(PD.DisplayOpenMode, 1)) 
    END 
END AS displayOpenMode, 

我應該提到這是SQL服務器2014 :)

+0

'TR.xType'應該是一個表,而不是包含多個值的單個字段。這違反了關係數據庫的原則規則。 [https://en.wikipedia.org/wiki/First_normal_form](https://en.wikipedia.org/wiki/First_normal_form) – Mike

回答

0

所以看起來你真的只是想輸入的字符串被解析。

從SQL 2016開始,您可以使用STRING_SPLIT,否則有許多自定義拆分實現。

兩個選項進行了討論here

在很大程度上將取決於你輸入的字符串是否一致。 (即相同數量的元素)

0

實際性能不應該差......如果你需要調試任何東西,這只是一點點笨重和嵌套函數可能是一個真正的痛苦。

爲此,您實際上可以使用交叉應用與表構造函數。這裏是一個例子,表明你可以完成同樣的事情,並保持事情清晰。

-- Something to test with... 
CREATE TABLE #TestData (DelimitedString VARCHAR(100)); 
INSERT #TestData(DelimitedString) VALUES ('aaaaaaaaa|bbbbbbbbb|cccccccccc|ddddddddddd|eeeeeeeeeee|ffffff'); 

SELECT 
    Item_1 = SUBSTRING(td.DelimitedString, 1, ISNULL(c1.CharLocation -1, 100)), 
    Item_3 = SUBSTRING(td.DelimitedString, c2.CharLocation + 1, ISNULL(c3.CharLocation - c2.CharLocation - 1, 100)), 
    Item_5 = SUBSTRING(td.DelimitedString, c4.CharLocation + 1, ISNULL(c5.CharLocation - c4.CharLocation - 1, 100)) 
FROM 
    #TestData td -- adding WAY more than necessary to demonstrate how much easier it is to manage... 
    CROSS APPLY (VALUES (NULLIF(CHARINDEX('|', td.DelimitedString, 1), 0))) c1 (CharLocation) 
    CROSS APPLY (VALUES (NULLIF(CHARINDEX('|', td.DelimitedString, c1.CharLocation + 1), 0))) c2 (CharLocation) 
    CROSS APPLY (VALUES (NULLIF(CHARINDEX('|', td.DelimitedString, c2.CharLocation + 1), 0))) c3 (CharLocation) 
    CROSS APPLY (VALUES (NULLIF(CHARINDEX('|', td.DelimitedString, c3.CharLocation + 1), 0))) c4 (CharLocation) 
    CROSS APPLY (VALUES (NULLIF(CHARINDEX('|', td.DelimitedString, c4.CharLocation + 1), 0))) c5 (CharLocation) 
    CROSS APPLY (VALUES (NULLIF(CHARINDEX('|', td.DelimitedString, c5.CharLocation + 1), 0))) c6 (CharLocation) 
    CROSS APPLY (VALUES (NULLIF(CHARINDEX('|', td.DelimitedString, c6.CharLocation + 1), 0))) c7 (CharLocation) 
    CROSS APPLY (VALUES (NULLIF(CHARINDEX('|', td.DelimitedString, c7.CharLocation + 1), 0))) c8 (CharLocation) 
    CROSS APPLY (VALUES (NULLIF(CHARINDEX('|', td.DelimitedString, c8.CharLocation + 1), 0))) c9 (CharLocation); 

結果...

Item_1  Item_3  Item_5 
------------ ------------ --------------- 
aaaaaaaaa cccccccccc eeeeeeeeeee 

正如你所看到的,它變得非常容易簡單地挑選出自己喜歡的任何元素...