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

时间:2018-10-19 01:03:42

标签: mysql join

我需要从“用户”表中获得不等于我的用户名的用户,但也不能在被阻止表中作为“被阻止者”。

仅使用 用户表,我正在做

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

但是,由于我添加了额外的“阻止”表,因此我需要对其进行进一步过滤。

mysql> describe users;
+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(11)      | NO   | PRI | NULL    | auto_increment |
| username  | varchar(255) | NO   |     | NULL    |                |
| password  | varchar(255) | NO   |     | NULL    |                |
| email     | varchar(255) | NO   |     | NULL    |                |
| city      | varchar(60)  | NO   |     | NULL    |                |
| state     | varchar(60)  | NO   |     | NULL    |                |
| lat       | decimal(8,6) | YES  |     | NULL    |                |
| lng       | decimal(9,6) | YES  |     | NULL    |                |
| interests | text         | YES  |     | NULL    |                |
| hash      | varchar(32)  | YES  |     | NULL    |                |
| active    | int(1)       | YES  |     | NULL    |                |
| avatar    | varchar(255) | YES  |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+
12 rows in set (0.00 sec)

mysql> describe blocked;
+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| id      | int(11)      | NO   | PRI | NULL    | auto_increment |
| blocker | varchar(255) | NO   |     | NULL    |                |
| blockee | varchar(255) | NO   |     | NULL    |                |
+---------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

我尝试过:

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 |
+----+-----------+----------+

它将返回不是测试用户的所有人,并且在兴趣列中具有与LIKE子句相同的值。

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

5 个答案:

答案 0 :(得分:2)

此查询将为您提供不是您并且未被您阻止的所有用户的列表。然后,您可以根据需要将其他条件(例如switch)添加到merge(progressSubscriber.pipe(tap(()=> this.upload_progress = Math.floor(data.loaded / data.total * 100 ) ), request$.pipe(tap(res)=>{},catchError((e)=>{..}) ).subscribe()子句中。

AND interests LIKE <string>

Demo on dbfiddle

答案 1 :(得分:0)

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

SELECT * FROM users WHERE username != 'myself' and user.username not in (select locker from blocked);

我认为它将为您正常工作

答案 2 :(得分:0)

应该有效-但是我又没有可用于测试的测试数据。

欢呼

SELECT * 
FROM users
WHERE ( 1 = 1 )
AND ( username ! = 'myself OR username not in ( select username from blocked ))
AND interests like '%string%';

在谓词中,您可能需要将OR更改为AND-因为我说过没有数据可以测试我的逻辑。

HTH!

答案 3 :(得分:0)

首先获取被阻止者列表,然后尝试将其与用户表进行匹配,如果找不到匹配项,则将有空被阻止者,而这些用户就是您想要的用户。

wait

答案 4 :(得分:0)

以下查询将执行您要查找的内容:

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%';

我整理了一个示例,您可以执行该示例以查看其行为:https://rextester.com/GPEC60793

这是整个演示的副本:

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;