T-SQL:检查小列表中的项目是否在大列表中

时间:2013-10-31 04:29:33

标签: sql-server-2008 tsql

如果我有一个颜色主列表(nvarchar字段),我想检查一个小颜色列表中的任何项是否在主列表中(nvarchar字段)。

e.g。主列表'红色|橙色|绿色|蓝色|白“

  1. 红色 | 橙色”=>真

  2. 白色 | 绿色”=>真

  3. 红色 |黑色”=>真

  4. “black | yellow”=>假

  5. “yellow”=>假

  6. 在T-SQL中解决此问题的最佳方法是什么?

    谢谢。

2 个答案:

答案 0 :(得分:3)

您可以创建一个表值函数:

create table tblMaster(color nvarchar(4000));
insert into tblMaster values ('red | orange | green | blue | white');
Go

-- Create a function to return data as rows of table.
CREATE FUNCTION [dbo].[SplitString](@String varchar(max), @Delimiter char(1))
returns @temptable TABLE (items varchar(max))
as
begin
    declare @idx int
    declare @slice varchar(max)

    select @idx = 1
        if len(@String)<1 or @String is null  return

    while @idx!= 0
    begin
        set @idx = charindex(@Delimiter,@String)
        if @idx!=0
            set @slice = left(@String,@idx - 1)
        else
            set @slice = @String

        if(len(@slice)>0)
            insert into @temptable(Items) values(@slice)

        set @String = right(@String,len(@String) - @idx)
        if len(@String) = 0 break
    end
return
end
Go

然后按如下所示编写查询以获得所需的结果:

Declare @color_mstr_list nvarchar(4000),@color_small_list nvarchar(4000);
select @color_mstr_list = color from tblMaster ;

select items into #temp from [dbo].[SplitString](@color_mstr_list,'|');

set @color_small_list = 'red | black';

with cte as
( 
select items from [dbo].[SplitString](@color_small_list,'|')
)
select case when COUNT(*) > 0 then 'True'
            else 'False'
            end  as Result   
from cte 
where exists ( select * from #temp T where T.items = cte.items )

drop table #temp;

答案 1 :(得分:2)

这是一个简单的解决方案:

  1. Table-Valued User-Defined FunctionXML nodes() method将列表转换为表格。
  2. INTERSECT方法检查第一个列表中的值是否包含在第二个
  3. 这是功能体:

    IF EXISTS (SELECT 1 FROM sysobjects WHERE id = object_id(N'fn_ConvertListToNVarcharTable') AND xtype IN (N'FN', N'IF', N'TF'))
    BEGIN
        DROP FUNCTION [dbo].[fn_ConvertListToNVarcharTable]
    END
    GO
    
    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    CREATE FUNCTION [dbo].[fn_ConvertListToNVarcharTable] (@List nvarchar(max))
    RETURNS @ResultRowset TABLE ([Value] NVARCHAR(250) PRIMARY KEY)
    AS
    BEGIN
        DECLARE @XML xml = N'<r><![CDATA[' + REPLACE(@List, '|', ']]></r><r><![CDATA[') + ']]></r>'
    
        INSERT INTO @ResultRowset ([Value])
        SELECT DISTINCT RTRIM(LTRIM(Tbl.Col.value('.', 'nvarchar(250)')))
        FROM @xml.nodes('//r') Tbl(Col)
    
        RETURN
    END
    
    GO
    

    这就是检查的方式:

    IF EXISTS(
        SELECT [Value] 
        FROM[fn_ConvertListToNVarcharTable]('red | orange')
        INTERSECT
        SELECT [Value] 
        FROM [fn_ConvertListToNVarcharTable]('red | orange | green | blue | white')
    )
    BEGIN
        SELECT 'True'
    END
    ELSE
    BEGIN
        SELECT 'False'
    END