1

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

例如 Master List 'red | 橙色 | 绿色 | 蓝色 | 白色的'

  1. 红色|橙色” => 真

  2. 白色|绿色” => 真

  3. 红色| 黑色” => 真

  4. “黑色 | 黄色” => 假

  5. “黄色” => 假

在 T-SQL 中解决这个问题的最佳方法是什么?

谢谢你。

4

2 回答 2

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;
于 2013-10-31T06:51:48.120 回答
2

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

  1. 表值用户定义函数XML nodes() 方法将列表转换为表。
  2. INTERSECT方法检查第一个列表中的值是否包含在第二个列表中

这是函数体:

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
于 2013-10-31T09:10:14.870 回答