如何比较SQLSERVER中的两个多值列

时间:2017-05-11 08:01:25

标签: sql sql-server

我的列包含一些值,如:;1;3;7;2; 另一列的值如下:;5;2;3;

我需要知道第一列中是否包含第二列(5,2或3)中的至少一个数字。 当然这是一个例子,我必须为几个记录做。

你有什么想法吗?

这是我的代码:

SELECT * 
FROM COMPANIES 
WHERE F_SKILLS IN F_CONVENTION

4 个答案:

答案 0 :(得分:3)

检查这个。

使用以下查询,您可以找到两列中出现的所有常用数字。

首先创建函数" [SplitLongString]":

        create  FUNCTION [dbo].[SplitLongString] 
        (
            @DelimitedString VARCHAR(MAX), 
            @Delimiter VARCHAR(100)
        )
        RETURNS 
        @tblArray TABLE 
        (
            ElementID INT IDENTITY(1,1), 
            Element VARCHAR(1000)
        )
        AS
        BEGIN   
            DECLARE
                @siIndex    INT,
                @siStart    INT,
                @siDelSize  INT
            SET @siDelSize  = LEN(@Delimiter)
            --loop through source string and add elements to destination table array
            WHILE LEN(@DelimitedString) > 0
            BEGIN
                SET @siIndex = CHARINDEX(@Delimiter, @DelimitedString)
                IF @siIndex = 0
                BEGIN
                    INSERT INTO @tblArray VALUES(@DelimitedString)
                    BREAK
                END
                ELSE
                BEGIN
                    INSERT INTO @tblArray VALUES(SUBSTRING(@DelimitedString, 1,@siIndex - 1))
                    SET @siStart = @siIndex + @siDelSize
                    SET @DelimitedString = SUBSTRING(@DelimitedString, @siStart , LEN(@DelimitedString) - @siStart + 1)
                END
            END

            RETURN 
        END

你可以交叉申请分开commo或半冒号。您将在列元素下获得公共元素。使用这些专栏进一步使用。

select A.*,y.Element common_element--,X.Element 
from #COMPANIES  A 
CROSS APPLY SplitLongString(F_SKILLS,';') y
CROSS APPLY SplitLongString(F_CONVENTION,';') X 
where  x.Element=y.Element and ( X.Element!=' ' or X.Element!= null)
  

输出:

enter image description here

如果您有任何疑问,请告诉我们。

答案 1 :(得分:1)

你可以使用dbo.Split的默认功能('5; 2; 3;',',')

如果您没有此功能,可以创建自己的

创建功能

CREATE FUNCTION SplitString
(    
      @Input NVARCHAR(MAX),
      @Character CHAR(1)
)
RETURNS @Output TABLE (
      Item NVARCHAR(1000)
)
AS
BEGIN
      DECLARE @StartIndex INT, @EndIndex INT

      SET @StartIndex = 1
      IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character
      BEGIN
            SET @Input = @Input + @Character
      END

      WHILE CHARINDEX(@Character, @Input) > 0
      BEGIN
            SET @EndIndex = CHARINDEX(@Character, @Input)

            INSERT INTO @Output(Item)
            SELECT SUBSTRING(@Input, @StartIndex, @EndIndex - 1)

            SET @Input = SUBSTRING(@Input, @EndIndex + 1, LEN(@Input))
      END

      RETURN
END
GO

创建功能后,您可以在查询中添加条件

select * from yourTableName tbl where (select * from dbo.SplitString(tbl.YourColumnWithSemicoluns,';')) in (select * from dbo.SplitString('5;2;3;',';'))

答案 2 :(得分:0)

如果它只是一些数字的有限集合,你可能可以逃脱一些简单的事情:

SELECT * FROM companies
 WHERE (f_skills LIKE '%;1;%' AND f_convention LIKE '%;1;%')
    OR (f_skills LIKE '%;2;%' AND f_convention LIKE '%;2;%')
    OR (f_skills LIKE '%;3;%' AND f_convention LIKE '%;3;%')
    ...

如果这不起作用......好吧,看起来页面上的其他一些答案可能会更全面......几乎令人尴尬的是这样。虽然,如果数字真的只是1-9,就像问题所示,我坚持我的答案。 :)我知道它相比看起来有点可怜,但是,说真的,它可能会起作用!如果没有,我会从Bhosale先生的那个开始。

答案 3 :(得分:0)

如果您正在使用SQL Server 2016,请查看string_split函数。

假设您没有,则可以按照之前的答案创建拆分功能。

如果这不是一个选项,你可以用CTE来做,但如果你有一个大的数据集,它可能效率很低。

create table test(col1 varchar(100), col2 varchar(100));
insert into test values ('a;b;c', 'c;d;e'),('a;b;c','d;e;f'), ('a;b;c', 'b;a;d')


;WITH SplitSting AS
(
    SELECT
        col1, col2, LEFT(col1,CHARINDEX(';',col1)-1) AS value
            ,RIGHT(col1,LEN(col1)-CHARINDEX(';',col1)) AS remainder
        FROM test
        WHERE col1 IS NOT NULL AND CHARINDEX(';',col1)>0
    UNION ALL
    SELECT
        col1, col2,LEFT(remainder,CHARINDEX(';',remainder)-1)
            ,RIGHT(remainder,LEN(remainder)-CHARINDEX(';',remainder))
        FROM SplitSting
        WHERE remainder IS NOT NULL AND CHARINDEX(';',remainder)>0
    UNION ALL
    SELECT
        col1, col2,remainder,null
        FROM SplitSting
        WHERE remainder IS NOT NULL AND CHARINDEX(';',remainder)=0
)
SELECT distinct col1, col2 FROM SplitSting
where ';'+col2+';' like '%;'+value+';%'