Mysql 使用join和where子句从两个表中获取行

Mysql 使用join和where子句从两个表中获取行,mysql,join,Mysql,Join,我需要从一个“用户”表中获取用户,该表不等于我的用户名,但也不作为“被阻止者”出现在被阻止的表中 仅使用用户表,我正在执行以下操作: SELECT * FROM users WHERE username != <myself> AND interests LIKE <string>; 我试图: SELECT * FROM users JOIN blocked ON users.username = blocked.blocker WHERE username != 'm

我需要从一个“用户”表中获取用户,该表不等于我的用户名,但也不作为“被阻止者”出现在被阻止的表中

仅使用用户表,我正在执行以下操作:

SELECT * FROM users WHERE username != <myself> AND interests LIKE <string>;
我试图:

SELECT * FROM users JOIN blocked ON users.username = blocked.blocker WHERE username != 'myself' AND blocked.blockee IS NULL;
伪查询如下所示:

"give me every user that's not equal to my username, but is also not a blockee where I am the blocker"
因此,如果我在阻塞表中有这些值:

+----+-----------+----------+
| id | blocker   | blockee  |
+----+-----------+----------+
|  1 | myself    | testuser |
+----+-----------+----------+
它将返回不是testuser的所有人,并且在兴趣列中具有与LIKE子句相同的值


我希望这是有道理的。我被卡住了。

如果您不关心性能,可以尝试子查询

从用户名为的用户中选择*“我自己”和user.username不在阻止的select locker中

我认为它会正确地为您工作

这应该是有效的-但是我没有您的测试数据来测试它

干杯

SELECT * 
FROM users
WHERE ( 1 = 1 )
AND ( username ! = 'myself OR username not in ( select username from blocked ))
AND interests like '%string%';
在谓词中,yo可能需要将OR更改为AND-正如我所说的,没有数据来测试我的逻辑


此查询将为您提供非您且未被您阻止的所有用户的列表。然后,您可以根据需要在WHERE子句中添加其他条件,例如和利息

SELECT u.*
FROM users u
LEFT JOIN blocked b
ON b.blockee != u.username AND b.blocker = 'myself'
WHERE u.username != 'myself' AND b.blockee IS NOT NULL

首先获取你的blockee列表,然后尝试将它们与你的用户表匹配,如果你找不到匹配项,你将拥有空blockee,而这些就是你想要的用户

SELECT u.*
FROM users u
LEFT JOIN ( SELECT b.blockee 
            FROM blocked b
            WHERE b.blocker = 'myself') as b
       ON o.username = b.blockee 
WHERE b.blockee IS NULL
  AND u.interests LIKE <string>
  AND u.username != 'myself' -- if blocker cant be the same as blockee
                             -- you dont need this one

下面是一个查询,它将完成您要查找的内容:

select *
from   users u
where  u.username != 'myself'
and    not exists (
    select 1
    from   blocked b
    where  b.blocker = 'myself'
    and    b.blockee = u.username
)
and    u.interests like '%what%';
我将一个示例放在一起,您可以执行它来查看它的行为:

以下是整个演示的副本:

drop table if exists demo_users;
drop table if exists demo_blocked;

create table demo_users (id int auto_increment, username varchar(255), interests text, primary key (id));
create table demo_blocked (id int auto_increment, blocker varchar(255), blockee varchar(255), primary key (id));

insert into demo_users (username, interests)
values ('myself', 'whatever'),
       ('testuser', 'blah'),
       ('somebody', 'foo'),
       ('nobody', 'whatfor');

insert into demo_blocked (blocker, blockee)
values ('myself', 'testuser');

select * from demo_users;
select * from demo_blocked;

select *
from   demo_users u
where  u.username != 'myself'
and    not exists (
    select 1
    from   demo_blocked b
    where  b.blocker = 'myself'
    and    b.blockee = u.username
)
and    u.interests like '%what%';

drop table demo_users;
drop table demo_blocked;

谢谢,但它不起作用。它返回除我之外的所有人,包括被阻止的testuser。它返回一个空集。我在测试数据库中运行了它,结果非常准确。你真的救了我一个深夜。我已经试了很长一段时间,当我放弃的时候又回来了。哈哈,漂亮的男人。谢谢你的帮助。接受回答。@IRGeekSauce-很高兴我能帮上忙。FWIW,@Nick用左连接的回答也是正确的。不确定哪种方法的性能更好,但两种方法的结果集应该是相同的。@Nick也谢谢你!我当时在手机上,这是我打开SO应用程序时单击的第一个通知。我也会投票给尼克。我很高兴@dossy提到了你的答案。这也很棒。如果我能接受两个答案,因为它们都是对的,我会的+1尽管如此@IRGeekSauce顺便说一句,我在写答案的时候创建了一个演示,但忘了链接。我在编辑中添加了它。嗨。请看,点击谷歌的“stackexchange家庭作业”和向下投票箭头鼠标悬停文本。这是一个显而易见且容易找到的基本faq,没有MCVE,不应回答,而应关闭并否决。总是用谷歌搜索你的问题/问题/目标的许多清晰、精确的短语,有字符串/名称的和没有字符串/名称的。然后关闭它。顺便说一句,这不是家庭作业。不管是不是家庭作业。我一定没有理解谷歌搜索stackexchange家庭作业的内容。可能是重复的
drop table if exists demo_users;
drop table if exists demo_blocked;

create table demo_users (id int auto_increment, username varchar(255), interests text, primary key (id));
create table demo_blocked (id int auto_increment, blocker varchar(255), blockee varchar(255), primary key (id));

insert into demo_users (username, interests)
values ('myself', 'whatever'),
       ('testuser', 'blah'),
       ('somebody', 'foo'),
       ('nobody', 'whatfor');

insert into demo_blocked (blocker, blockee)
values ('myself', 'testuser');

select * from demo_users;
select * from demo_blocked;

select *
from   demo_users u
where  u.username != 'myself'
and    not exists (
    select 1
    from   demo_blocked b
    where  b.blocker = 'myself'
    and    b.blockee = u.username
)
and    u.interests like '%what%';

drop table demo_users;
drop table demo_blocked;