根据上表 STProcedure 中显示的现有场景,可能存在与单个 STProcedure 相关的组合组。在上图中可以看出,以下关系适用于 STProcedureID 和 GroupID
要求 GroupID 应在单行查询中使用分隔符“_”进行拆分。
我能够通过使用用户定义的函数找到解决方案,如下所示
ALTER FUNCTION E1.fnSplit (@sInputList udtStringMax, @sDelimiter udtStringMax = '_')
RETURNS @List TABLE (item udtStringMax,CNT INT IDENTITY(1,1))
BEGIN
DECLARE @sItem udtStringMax
WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
BEGIN
SELECT
@sItem=SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1),
@sInputList=SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))
IF LEN(@sItem) > 0
INSERT INTO @List SELECT @sItem
END
IF LEN(@sInputList) > 0
INSERT INTO @List SELECT @sInputList -- Put the last item in
RETURN
END
SELECT * FROM E1.E_STProcedure WHERE STProcedureID IN
(SELECT item FROM E1.fnSplit((SELECT GroupID FROM E1.E_STProcedure WHERE STProcedureID='||OWNER||'),'_'))
其中||OWNER||
是个人 STProcedureID 而 E1 是我拥有的数据库架构
由于系统是在MTMS(多租户多模式)环境中实现的,因此每个查询都依赖于模式并且具有100多个模式,上述代码仅适用于 E1 架构。
我得出的结论是,在SQL中使用单行查询分割字符串(带分隔符)可能存在一种解决方法,而不使用用户定义的函数,因为唯一的另一个选择是替换并执行查询每个模式及其标记。
答案 0 :(得分:1)
好吧,为了争论,让我们暂时跳过CTE,而不是做长而丑陋的&#34;用一些xml。我将在这里留下你的一行休息。这个基础知识是从Brad Shulz通过Aaron Bertrand提取的。我从一个int列表改变了,缩短了一点,把它从一个函数中取出来,然后把它放在一行上。
SELECT * FROM E_STProcedure WHERE STProcedureID IN
(SELECT Item FROM (SELECT Item = b.i.value('(./text())[1]', 'VARCHAR(MAX)') FROM (SELECT x = CONVERT(XML, '<i>' + REPLACE(Group_ID, '_', '</i><i>') + '</i>').query('.') FROM E_STProcedure WHERE STProcedureID='||OWNER||') a CROSS APPLY x.nodes('i') b(i)) c WHERE Item IS NOT NULL)
考虑到一些换行符,它会更好看:
SELECT *
FROM E_STProcedure
WHERE STProcedureID IN (
SELECT Item
FROM (SELECT Item = b.i.value('(./text())[1]', 'VARCHAR(MAX)')
FROM (SELECT x = CONVERT(XML, '<i>' +
REPLACE(Group_ID, '_', '</i><i>') +
'</i>').query('.')
FROM E_STProcedure
WHERE STProcedureID='||OWNER||') a
CROSS APPLY
x.nodes('i') b(i)
) c
WHERE Item IS NOT NULL)
仍然可以作为CTE完成,但我没有看到收益。
答案 1 :(得分:0)
我能够在同事的帮助下制定以下解决方案
SELECT * FROM E1.E_STProcedure WHERE STProcedureID IN
(SELECT ST2.STProcedureID FROM E1.E_STProcedure ST1
JOIN E1.E_STProcedure ST2 ON ST1.GroupID LIKE '%'+ST2.STProcedureID+'%'
WHERE ST1.STProcedureID ='||OWNER||')
这里发生的是WHERE
子句肯定会将结果从ST1
相对于相应的GUID
||OWNER||
减少到单个记录。
让我们通过以下示例进行简化
WHERE ST1.STProcedureID ='17bfa492-8464-423f-a5f4-32978186e112'
JOIN
语句显示果汁,检查来自ST1.GroupID
的单个条目是否包含来自ST2.STProcedureID
的子字符串,如下所示
E1.E_STProcedure ST1
JOIN
E1.E_STProcedure ST2
ON
ST1.GroupID LIKE '%'+ST2.STProcedureID+'%'
我希望代码对你们所有人来说都是可读的。