如何在JOIN查询中匹配多个条件

我想检索所有符合多个加入条件的用户。

这是此数据库的简化示例:

create table users(id int,name varchar);
insert into users values(1,"caroline"); 
insert into users values(2,"simon");
insert into users values(3,"jose");
insert into users values(4,"robert");
create table tags(value varchar,user_id integer);

insert into tags values("a",1); insert into tags values("b",1);
insert into tags values("a",2);insert into tags values("b",3);
insert into tags values("c",4);

我想让用户拥有标签“ a”和标签“ b”(caroline)。

如果我运行以下查询: SELECT * from users INNER JOIN tags ON users.id = tags.user_id WHERE tags.value IN ('a','b');

它返回与两个条件之一匹配的所有用户:

1|caroline|a|1
1|caroline|b|1
2|simon|a|2
3|jose|b|3

如果我运行此查询:

SELECT * FROM users where users.id IN (
SELECT users.id from users INNER JOIN tags ON users.id = tags.user_id WHERE tags.value = 'a'
INTERSECT
SELECT users.id from users INNER JOIN tags ON users.id = tags.user_id WHERE tags.value = 'b');

有效。只有卡罗琳才回来。

但是在这种情况下,它是3个选择查询。但这是实际用法,如果我要搜索5个标签,它将是6个选择查询。

是否有更好的解决方案来创建子查询?

crazyboylp 回答:如何在JOIN查询中匹配多个条件

您可以使用聚合:

select u.id,u.name
from users u
inner join tags t on u.id = t.user_id 
where t.value in ('a','b')
group by u.id,u.name
having count(distinct t.value) = 2

该查询将同一用户的所有tags记录分组,对标记值列表进行过滤,并确保它们都存在。

如果要检查6个标签,则可以执行以下操作:

select u.id,'b','c','d','e','f')
group by u.id,u.name
having count(distinct t.value) = 6
,

一种方法使用聚合来查找同时具有两个所需标签的用户。然后,加入users表以输入实际的用户名。

SELECT
    u.id,u.name
FROM users u
INNER JOIN
(
    SELECT user_id
    FROM tags
    WHERE value IN ('a','b')
    GROUP BY user_id
    HAVING MIN(value) <> MAX(value)
) t
    ON u.id = t.user_id;

使用自我加入的另一种选择:

SELECT
    u.id,u.name
FROM users u
INNER JOIN tags t1
    ON u.id = t1.user_id
INNER JOIN tags t2
    ON u.id = t2.user_id
WHERE
    t1.value = 'a' AND
    t2.value = 'b';
,

有多种解决方案。 一种可能是对需要检查的每个标签使用标签表上的联接:

SELECT u.id,u.name FROM users u
INNER JOIN tags t1 ON (u.id = t1.user_id AND t1.value = 'a')
INNER JOIN tags t2 ON (u.id = t2.user_id AND t2.value = 'b');

另一个可能是使用group_concat:

SELECT u.id,u.name,GROUP_CONCAT(t.value ORDER BY t.value)
FROM users u
JOIN tags t on u.id = t.user_id
GROUP BY u.id,u.name
HAVING GROUP_CONCAT(t.value) = 'a,b'

为确保获得与a和b以外的其他标签匹配的用户,可以使用以下方式更改having子句:

HAVING GROUP_CONCAT(t.value) LIKE '%a%b%'
,

您也可以多次针对同一张表

SELECT users.name FROM users 
INNER JOIN tags t1 ON users.id = t1.user_id AND t1.value = 'a'
INNER JOIN tags t2 ON users.id = t1.user_id AND t1.value = 'b'
WHERE t1.user_id=t2.user_id
AND users.id=t1.user_id

不确定哪个答案更有效?

,

您可以根据需要更改cn > 1。 (例如:如果要搜索5个标签,则cn > 4

    SELECT * FROM (
    SELECT name,count(*) cn FROM users 
      INNER JOIN tags ON 
      users.id = tags.user_id 
      WHERE tags.value IN ('a','b')
      group by name
    ) WHERE cn > 1;
本文链接:https://www.f2er.com/3160826.html

大家都在问