0

I have a 20 Column in a Table Col1, Col2, Col3 .... Col20. RowNo column is a primary column, Col1 to Col20 is a not null int column

in each Column has unique data for single row(means Col1 has 10 so in Col2 to Col20 values is not repeat). table has approx 100000 records.

i have a 10 values like 18, 3, 15, 16, 11, 5, 41, 61, 43, 80 i want to search each records in all 20 column.

select only those rows which has all 10 values in col1 to col20

For Ex. 18 can be match in col1 to col20

as per the below data return 4th row result may be return more then one row

enter image description here

4

5 回答 5

2
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
于 2013-06-28T12:09:33.773 回答
0

另一种选择:将数据复制到便于查询的表中。

桌子:

   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
于 2013-06-28T12:18:58.253 回答
0

在你回答之前,我使用下面的函数,它返回一个匹配计数并得到 where count = 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
于 2013-07-04T17:01:57.083 回答
0

您首先将过滤器值以逗号分隔,然后使用下面的函数将其放在不同行的表中

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

现在为这个表声明一个游标来得到一个一个值

现在在这个光标旁边使用

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
;

在不同的行中获取一行的所有列并运行它的循环并检查它的过滤器值,基本上在游标上方你必须运行另一个游标

它丑陋,冗长,但总比没有好:-)

于 2013-06-28T12:25:44.840 回答
0

您还可以使用unpivot来减少打字col1, col2, ..., colN(特别是如果将来会有所不同)。你可以这样尝试:

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
于 2013-07-04T23:11:54.800 回答