Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 匹配多列中的数据_Sql - Fatal编程技术网

Sql 匹配多列中的数据

Sql 匹配多列中的数据,sql,Sql,我在表Col1,Col2,Col3中有一个20列。。。。Col20。 RowNo列是主列,Col1到Col20是NOTNULL int列 在每一列中,每一行都有唯一的数据(意味着Col1有10个,因此Col2到Col20中的值不会重复)。表中有大约100000条记录 我有10个值,比如18,3,15,16,11,5,41,61,43,80,我想搜索所有20列中的每个记录 仅选择在col1到col20中包含所有10个值的行 例如,18可以在col1到col20中匹配 根据以下数据,返回第4行结果可

我在表Col1,Col2,Col3中有一个20列。。。。Col20。
RowNo列是主列,Col1到Col20是NOTNULL int列

在每一列中,每一行都有唯一的数据(意味着Col1有10个,因此Col2到Col20中的值不会重复)。表中有大约100000条记录

我有10个值,比如18,3,15,16,11,5,41,61,43,80,我想搜索所有20列中的每个记录

仅选择在col1到col20中包含所有10个值的行

例如,18可以在col1到col20中匹配

根据以下数据,返回第4行结果可能会返回多行

SELECT * FROM
yourTable
WHERE
  CASE WHEN 18 IN (col1, col2, col3, ...col20) THEN 1 ELSE 0 END
+ CASE WHEN  3 IN (col1, col2, col3, ...col20) THEN 1 ELSE 0 END
+ CASE WHEN 15 IN (col1, col2, col3, ...col20) THEN 1 ELSE 0 END
+ CASE WHEN 16 IN (col1, col2, col3, ...col20) THEN 1 ELSE 0 END
+ CASE WHEN 11 IN (col1, col2, col3, ...col20) THEN 1 ELSE 0 END
+ CASE WHEN  5 IN (col1, col2, col3, ...col20) THEN 1 ELSE 0 END
+ CASE WHEN 41 IN (col1, col2, col3, ...col20) THEN 1 ELSE 0 END
+ CASE WHEN 61 IN (col1, col2, col3, ...col20) THEN 1 ELSE 0 END
+ CASE WHEN 43 IN (col1, col2, col3, ...col20) THEN 1 ELSE 0 END
+ CASE WHEN 80 IN (col1, col2, col3, ...col20) THEN 1 ELSE 0 END
= 10

另一种选择:将数据复制到查询友好的表中

下表:

   CREATE TABLE [dbo].[tblX](
        [ID] [int] IDENTITY(1,1) NOT NULL,
        [ColN] [int] NULL,
        [Value] [int] NULL,
        [RowNo] [int] NULL
    );
将数据复制到:

    INSERT INTO tblX(RowNo, ColN, Value)
    SELECT RowNo, 1, Col1 FROM tblCols;
    INSERT INTO tblX(RowNo, ColN, Value)
    SELECT RowNo, 2, Col2 FROM tblCols;
    INSERT INTO tblX(RowNo, ColN, Value)
    SELECT RowNo, 3, Col3 FROM tblCols;
    INSERT INTO tblX(RowNo, ColN, Value)
    ...
    INSERT INTO tblX(RowNo, ColN, Value)
    SELECT RowNo, 20, Col20 FROM tblCols;
查询:

    SELECT
        * 
    FROM
        tblX
        WHERE RowNo IN 
        (
                SELECT 
                    RowNo
                FROM
                    tblX
                WHERE
                    Value IN (18, 3, 15, 16, 11, 5, 41, 61, 43, 80)
                GROUP BY RowNo
                HAVING COUNT(*) = 10 -- the number of numbers above
         ) 
    ORDER BY RowNo, ColN

首先以逗号分隔的形式获取筛选器值,然后使用下面的函数在不同行的表中获取它

CREATE FUNCTION [dbo].[Split]
(
@String VARCHAR(200),
@Delimiter VARCHAR(5)
)

RETURNS @SplittedValues TABLE
(
OccurenceId SMALLINT IDENTITY(1,1),
SplitValue VARCHAR(200)
)

AS

BEGIN

DECLARE @SplitLength INT

WHILE LEN(@String) > 0
BEGIN

SELECT @SplitLength = (CASE CHARINDEX(@Delimiter,@String) WHEN 0 THEN

LEN(@String) ELSE CHARINDEX(@Delimiter,@String) -1 END)

INSERT INTO @SplittedValues

SELECT SUBSTRING(@String,1,@SplitLength)

SELECT @String = (CASE (LEN(@String) - @SplitLength) WHEN 0 THEN ''

ELSE RIGHT(@String, LEN(@String) - @SplitLength - 1) END)

END

RETURN
现在为该表声明一个cusor以逐个获取值

现在,在这一侧,使用

SELECT s.name SchemaName, t.name TableName, c.name ColumnName
FROM sys.columns c INNER JOIN
     sys.tables t ON c.object_id = t.object_id INNER JOIN
     sys.schemas s ON t.schema_id = s.schema_id
;
获取不同行中一行的所有列,并运行其循环并使用其检查筛选值, 基本上,在上面的游标内,您必须运行另一个游标


它丑陋、冗长,但总比什么都没有好:-)

在您回答之前,我使用下面的函数,它返回匹配计数并获取计数=10的位置

Create FUNCTION [dbo].[MatchRows]
(
    @id int, 
    @No1 int, 
    @No2 int,
    @No3 int,
    @No4 int,
    @No5 int,
    @No6 int,
    @No7 int,
    @No8 int,
    @No9 int,
    @No10 int   
)
RETURNS bit
AS
BEGIN
    Declare @ReturnVal bit = 0; 
    Declare @Allvalue varchar(max);
    Declare @CntMatch int;

    SELECT  @Allvalue = ',' + Convert(varchar(3),No1)+ ',' +
                        Convert(varchar(3),No2)+ ',' +
                        Convert(varchar(3),No3)+ ',' +
                        Convert(varchar(3),No4)+ ',' +
                        Convert(varchar(3),No5)+ ',' +
                        Convert(varchar(3),No6)+ ',' +
                        Convert(varchar(3),No7)+ ',' +
                        Convert(varchar(3),No8)+ ',' +
                        Convert(varchar(3),No9)+ ',' +
                        Convert(varchar(3),No10)+ ',' +
                        Convert(varchar(3),No11)+ ',' +
                        Convert(varchar(3),No12)+ ',' +
                        Convert(varchar(3),No13)+ ',' +
                        Convert(varchar(3),No14)+ ',' +
                        Convert(varchar(3),No15)+ ',' +
                        Convert(varchar(3),No16)+ ',' +
                        Convert(varchar(3),No17)+ ',' +
                        Convert(varchar(3),No18)+ ',' +
                        Convert(varchar(3),No19)+ ',' +
                        Convert(varchar(3),No20)+ ','
    FROM    DrawFinalResult
    WHERE   ID = @ID;

    SET @CntMatch = 0;

    Select @CntMatch += (CASE  WHEN CHARINDEX(','+ Convert (varchar(3),@No1) +',',@Allvalue) > 0 THEN 1 Else 0 END); 
    Select @CntMatch += (CASE  WHEN CHARINDEX(','+ Convert (varchar(3),@No2) +',',@Allvalue) > 0 THEN 1 Else 0 END); 
    Select @CntMatch += (CASE  WHEN CHARINDEX(','+ Convert (varchar(3),@No3) +',',@Allvalue) > 0 THEN 1 Else 0 END); 
    Select @CntMatch += (CASE  WHEN CHARINDEX(','+ Convert (varchar(3),@No4) +',',@Allvalue) > 0 THEN 1 Else 0 END); 
    Select @CntMatch += (CASE  WHEN CHARINDEX(','+ Convert (varchar(3),@No5) +',',@Allvalue) > 0 THEN 1 Else 0 END); 
    Select @CntMatch += (CASE  WHEN CHARINDEX(','+ Convert (varchar(3),@No6) +',',@Allvalue) > 0 THEN 1 Else 0 END); 
    Select @CntMatch += (CASE  WHEN CHARINDEX(','+ Convert (varchar(3),@No7) +',',@Allvalue) > 0 THEN 1 Else 0 END); 
    Select @CntMatch += (CASE  WHEN CHARINDEX(','+ Convert (varchar(3),@No8) +',',@Allvalue) > 0 THEN 1 Else 0 END); 
    Select @CntMatch += (CASE  WHEN CHARINDEX(','+ Convert (varchar(3),@No9) +',',@Allvalue) > 0 THEN 1 Else 0 END); 
    Select @CntMatch += (CASE  WHEN CHARINDEX(','+ Convert (varchar(3),@No10) +',',@Allvalue) > 0 THEN 1 Else 0 END); 

    Set @ReturnVal = (CASE WHEN @CntMatch = 10 THEN 1 ELSE 0 END);

    RETURN @ReturnVal
END

您还可以使用
unpivot
来减少键入
col1、col2、…、colN
(特别是如果将来会有所不同的话)。您可以像这样尝试smth:

create table Unpivoted (RoNo int, Value int primary key)

insert Unpivoted
select
  upvt.RoNo, upvt.Value
from (
  select * from YourTable
) src
unpivot (
  Value for ColNo in (
    col1, col2, col3, col4, col5, 
    col6, col7, col8, col9, col10 -- etc.
  )
) upvt

select
  *
from YourTable yt
join (
  select
    RoNo
  from Unpivoted
  where
    Value in (
      18, 3, -- etc. N values at all
    )
  group by
    RoNo
  having
    count(*) = N
) x on 
  yt.RoNo = x.RoNo

drop table Unpivoted

将数据添加为文本,然后我们可以将其复制/粘贴到sql-FIDLE。除了列
col1
col20
之外,您的表是否还有主键/唯一ID字段?RowNo列是主列,col1到col20是非空int列。您的目标是什么SGBD?我使用的是MSSQL-2008。无法理解这个问题出了什么问题,所以其他用户的投票结果是负数