T-SQL - 验证所有值是否包含在select语句的结果中

时间:2018-04-18 14:00:25

标签: sql-server tsql split sql-server-2016

假设我有一个函数,我在其中传递逗号分隔的值列表。然后我有另一个函数返回一个表。如何验证逗号分隔列表中的每个值是否包含在第二个函数的结果中?如果逗号分隔列表包含的值不在第二个函数的结果中,则结果必须为FALSE。

有效方案:

输入:A,B,C

第二个函数的结果:A,B,C,D

无效的方案:

输入:A,B,C,D

第二个函数的结果:A,B,C

提前致谢。

1 个答案:

答案 0 :(得分:1)

这样的事情:

DECLARE @input VARCHAR(100)='1,3,4';

WITH splittedInput AS
(
    SELECT val.value('text()[1]','int') As theInt
    FROM
    (
        SELECT CAST('<x>' + REPLACE(@input,',','</x><x>') + '</x>' AS XML) AS singleValue
    ) AS x
    CROSS APPLY x.singleValue.nodes('/x') As y(val)
)
SELECT *
FROM splittedInput AS si 
LEFT JOIN (VALUES(1),(2),(3),(4)) AS t(x) ON t.x=si.theInt
WHERE t.x IS NULL;

单独运行此部件

    SELECT val.value('text()[1]','int') As theInt
    FROM
    (
        SELECT CAST('<x>' + REPLACE(@input,',','</x><x>') + '</x>' AS XML) AS singleValue
    ) AS x
    CROSS APPLY x.singleValue.nodes('/x') As y(val)

您会看到这会将逗号分隔的输入作为派生表返回。

如果您使用的是SQL Server 2016+,则可以使用STRING_SPLIT(),这样可以使整个事情变得更加简单。

示例是使用VALUES创建模拟结果以返回1,2,3和4. LEFT JOIN将返回所有结果值以及可连接输入值。如果没有,则为NULL。在没有WHERE子句的情况下运行它以查看差异。

尝试在输入中添加一个值,该值不包含在输出中并再次尝试脚本。

更新

使用SELECT这样的

SELECT CASE WHEN COUNT(*)>0 THEN 0 ELSE 1 END AS ResultIsValid

如果需要,您将获得一个01标记有效性以返回此内容。

更新2:使用STRING_SPLIT()

2016版本MS引入了一些新的字符串方法one of them is STRING_SPIT()

我目前无法对此进行测试(需要SQL-Server 2016+),但这应该可行

SELECT *
FROM STRING_SPLIT(@input,',') AS ss 
LEFT JOIN (VALUES(1),(2),(3),(4)) AS t(x) ON t.x=ss.value
WHERE t.x IS NULL;