我们可以在子查询中使用LIKE而不是IN

时间:2018-03-08 08:42:41

标签: sql sql-server

我正在使用以下sql查询

SELECT * FROM TestTable WHERE keyword IN ( Select Tags from Tags)
表格中的

关键字存储为keyword1, keyword2, keyword3

如果是单个关键字,上面的查询工作正常,但我有多个关键字,我需要在

中搜索每个关键字

我不认为上面的问题是给我正确的结果,因为我正在比较

keyword1, keyword2, keyword3IN (keyword1, keyword2, keyword3)不匹配我尝试使用

 SELECT * FROM TestTable WHERE keyword LIKE ( Select Tags from Tags)

但它会产生错误

  

子查询返回的值超过1。这是不允许的   子查询跟随=,!=,<,< =,>,> =或当子查询用作   一种表达。声明已经终止。

可以使它工作,所以它循环遍历table1中的每个关键字,Table2是tempTable并且在三行中有这些keyword1, keyword2, keyword3

SQL FIDDLE

小提琴是样本数据

4 个答案:

答案 0 :(得分:4)

如果你想使用模式匹配,你可以这样做。

使用EXISTS

SELECT * FROM TABLE1 T1
WHERE EXISTS
(
 SELECT 1 FROM TABLE2 T2 WHERE T1.Keyword LIKE '%' + T2.keyword + '%'
)

使用加入

SELECT * FROM TABLE1 T1
INNER JOIN TABLE2 T2 ON T1.Keyword LIKE '%' + T2.keyword + '%'

如果完全匹配,您可以执行以下操作。

SELECT * FROM TABLE1 T1
INNER JOIN TABLE2 T2 ON T1.Keyword = T2.keyword 

答案 1 :(得分:0)

关于您的错误: 您的子查询会为您提供多个结果,LIKE运算符无法比较1到1之多。
IN运算符是一个好主意,但是 如果您要在table2中找到与完全匹配的内容table1中的记录(或更多),那么这就是您的目标:

SELECT *
FROM TABLE1
INNER JOIN TABLE2 ON TABLE2.keyword = TABLE1.keyword

如果您要查找table2 SIMILAR 的任何内容,而table1的一个或多个记录使用此内容:

SELECT *
FROM TABLE1
INNER JOIN TABLE2 ON TABLE2.keyword+'%' LIKE TABLE1.keyword

答案 2 :(得分:0)

可以使用Dynamic SQL完成。检查具有性能优势的方法的不同方法:

SQLFiddle:

create table a (keyword varchar(20))
create table b (keyword varchar(20))

insert into a values ('the'), ( 'quick'), ( 'brown'), ( 'fox'), ( 'jumped'), ( 'over'), ( 'the'), ( 'lazy'), ( 'dog')
insert into b values ('the'), ( 'quic'), ( 'browns'), ( 'x'), ( 'jumped'), ('quick,brown,fox')

Declare @keywords as nvarchar(max)
Declare @Sql as nvarchar(max)

select @keywords = 
    stuff((
        select distinct ' or keyword like ''%' + [keyword] + '%'''
      --select distinct ' or keyword = ''' + [keyword] + '''' --if exact match is required
        from b
        for xml path('')
    ),1,3,'')

set @Sql = 'SELECT * FROM a WHERE ' + @keywords 

exec(@Sql)

不是小提琴:

<?php
    $pagesToLoad = array("file1.php","file2.php","file3.php","file4.php","file5.php","file6.php","file7.php","file8.php","file9.php","file10.php");

    $randomPageToLoadA = $pagesToLoad[mt_rand(0, count($pagesToLoad) -1)];
    $randomPageToLoadB = $pagesToLoad[mt_rand(0, count($pagesToLoad) -1)];
    $randomPageToLoadC = $pagesToLoad[mt_rand(0, count($pagesToLoad) -1)];
    $randomPageToLoadD = $pagesToLoad[mt_rand(0, count($pagesToLoad) -1)];
    $randomPageToLoadE = $pagesToLoad[mt_rand(0, count($pagesToLoad) -1)];
?>

答案 3 :(得分:0)

如果您使用的是sql server或+,请使用string_split函数,否则:

创建功能拆分:

CREATE  FUNCTION [dbo].[fn_split](
@str VARCHAR(MAX),
@delimiter CHAR(1)
)
RETURNS @returnTable TABLE (idx INT PRIMARY KEY IDENTITY, item VARCHAR(8000))
AS
BEGIN
DECLARE @pos INT
SELECT @str = @str + @delimiter
WHILE LEN(@str) > 0 
    BEGIN
        SELECT @pos = CHARINDEX(@delimiter,@str)
        IF @pos = 1
            INSERT @returnTable (item)
                VALUES (NULL)
        ELSE
            INSERT @returnTable (item)
                VALUES (rtrim(ltrim(SUBSTRING(@str, 1, @pos-1))))
        SELECT @str = SUBSTRING(@str, @pos+1, LEN(@str)-@pos)       
    END
RETURN
END

将您的值拆分为:

select * from tmp20180308 t1 CROSS APPLY fn_split(t1.keyword, ',') t2
inner join table2 t3 on t3.keyword=t2.item

并与其他表格进行联接