相当简短的SQL语句,但有许多长的' SUBSTRING'陈述,这可以更好地进行优化吗?

时间:2017-09-29 12:56:25

标签: sql tsql sql-server-2014

这是SELECT语句的一部分。逻辑很简单,但我觉得必须要有一种方法来缩短第3和第4行。

' TR.xType'字符串看起来像"用户| true | null"最有可能的。第3行和第4行正在检查该中间值是否为真#39;在这种情况下,在使用它之前是一个有效的布尔值。

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 Server 2014上:)

2 个答案:

答案 0 :(得分:0)

所以看起来你真的只想解析输入字符串。

从SQL 2016开始,您可以使用STRING_SPLIT,否则会有许多自定义拆分实现。

讨论了两个选项here

很多将取决于您的输入字符串是否一致。 (即相同数量的元素)

答案 1 :(得分: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

正如您所看到的,只需选择您喜欢的任何元素即可轻松实现......