Получение строк из двух таблиц с помощью оператора join и where - PullRequest
0 голосов
/ 19 октября 2018

Мне нужно получить пользователей из таблицы 'users', которые не совпадают с моим именем пользователя, но также не находятся в заблокированной таблице как 'blockee'.

Используя только таблицу пользователей, я делаю:

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

Она вернет всех, кто является не testuser и имеет те же значения в столбце интересов, что и предложение LIKE.

Я надеюсь, что этоимеет смысл.Я застрял.

Ответы [ 5 ]

0 голосов
/ 19 октября 2018

Вот запрос, который будет делать то, что вы ищете:

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;
0 голосов
/ 19 октября 2018

Сначала получите список ваших блокировщиков, затем попытайтесь сопоставить их с вашей таблицей пользователей, если вы не можете найти совпадения, у вас будет нулевой блокировщик, и это те пользователи, которых вы хотите.

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
0 голосов
/ 19 октября 2018

Это должно работать - но опять же у меня нет ваших тестовых данных для проверки.

Приветствия

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

в предикате йо, возможно, понадобитсячтобы изменить ИЛИ на И - как я уже сказал, нет данных для проверки моей логики.

HTH!

0 голосов
/ 19 октября 2018

Этот запрос выдаст вам список всех пользователей, которые не являются вами и не заблокированы вами.Затем вы можете добавить другие условия (например, AND interests LIKE <string>) к предложению 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

Демонстрация на dbfiddle

0 голосов
/ 19 октября 2018

Если вам не важна производительность, вы можете попробовать подзапрос.

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

Я думаю, он будет работать правильно для вас

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...