使用SQL搜索确切的值

时间:2014-03-27 10:59:11

标签: sql exact-match

我有这种表:

a   b

8   7
8   2
9   7
9   2
9   3

我希望获得一个“a”值,使其具有“b”的确切搜索值。例如,如果我搜索(7,2),我希望查询返回8,如果我搜索(7,2,3),我希望它返回9,否则它必须返回Null:

Search      Result
(7,2)       8
(7,2,3)     9
(7,3)       Null
(7,2,4)     Null
...

是否可以在不使用“分组依据”连接的情况下执行此操作?

[编辑]对于“通过连接分组”,我的意思是像MySql中的GROUP_CONCAT()或任何字符串函数。

4 个答案:

答案 0 :(得分:0)

group by /连接方法有效。另一种方法是group by,带有having子句:

select a
from table t
group by a
having sum(case when b = 7 then 1 else 0 end) = 1 and
       sum(case when b = 2 then 1 else 0 end) = 1 and
       sum(case when b not in (7, 2) then 1 else 0 end) = 0;

我们的想法是计算每个值中匹配的值。实际上,您可以使用字符串操作执行此操作,但这些操作在数这是一个"将军"使用in执行此操作的方式以及您要查找的值的数量:

select a
from table t
group by a
having count(*) = 2 and
       count(distinct (case when b in (2, 7) then b end));

答案 1 :(得分:0)

在SQL Server中

SELECT a FROM tableName
WHERE a NOT IN ( SELECT a FROM (   
                               SELECT a,
                               CASE WHEN CHARINDEX(b,@searchTerm)=0 
                               THEN 0 ELSE 1 END as Result
                               FROM tableName
                               )z
                  WHERE z.Result=0
               )

我正在使用CHARINDEX()函数来检查搜索词是否存在。

答案 2 :(得分:0)

不确定你的意思"通过连接分组" - 我不认为可以在没有 group by 的情况下完成

您没有指定DBMS,因此这是ANSI SQL:

with search_values (val) as (
   values (7), (2)
)
-- first part gets all those that do have the search values
-- but will also include those rows that have more than the searched ones
select a
from data
where b in (select val from search_values)
group by a
having count(distinct b) = (select count(*) from search_values)

intersect
-- the intersect then filters out those that have exactly the search values

select a
from data
group by a
having count(distinct b) = (select count(*) from search_values);

SQLFiddle示例:http://sqlfiddle.com/#!15/dae93/1

将CTE用于"搜索值"避免重复它们并避免"硬编码"要搜索的项目数。如果您查找7,2,3,则只需向CTE添加另一个值

不是使用intersect,而是可以使用共同相关的子查询重写

with search_values (val) as (
   values (7), (2)
)
select d1.a
from data d1
where d1.b in (select val from search_values)
group by d1.a
having count(distinct d1.b) = (select count(*) from search_values)
   and count(distinct d1.b) = (select count(*) from data d2 where d2.a = d1.a);

答案 3 :(得分:0)

另一种方法是使用 INTERSECT

然而,第一种情况似乎仍然需要破解(返回8,9而不是8)。

这是SQL代码:

--(7,2) => 8,9 (instead of 8) :(
   SELECT  distinct(a)
    FROM   t1
    WHERE  b = 7
   INTERSECT
   SELECT  distinct(a)
    FROM   t1
    WHERE  b = 2

--(7,2,3) => 9
   SELECT  distinct(a)
    FROM   t1
    WHERE  b = 7
   INTERSECT
   SELECT  distinct(a)
    FROM   t1
    WHERE  b = 2
   INTERSECT
   SELECT  distinct(a)
    FROM   t1
    WHERE  b = 3

--(7,4) => NULL
   SELECT  distinct(a)
    FROM   t1
    WHERE  b = 7
   INTERSECT
   SELECT  distinct(a)
    FROM   t1
    WHERE  b = 4

--(7,2,4) => NULL
   SELECT  distinct(a)
    FROM   t1
    WHERE  b = 7
   INTERSECT
   SELECT  distinct(a)
    FROM   t1
    WHERE  b = 2
   INTERSECT
   SELECT  distinct(a)
    FROM   t1
    WHERE  b = 4

Fiddle Demo