INNER JOIN + LEFT JOIN(双重过滤)

时间:2015-10-30 04:12:21

标签: mysql left-join

我试图过滤我的表,其中用户在一个表中有一行,而在另一个表中没有行。这是我的表格结构:

这里是一个SQL小提琴: http://sqlfiddle.com/#!9/6e27ed/2

CREATE TABLE users (
   user_id INT(11) AUTO_INCREMENT,
   name VARCHAR(25),
   PRIMARY KEY(user_id)
);

CREATE TABLE photos (
   photo_id INT(11) AUTO_INCREMENT,
   user_id INT(11) NOT NULL,
   PRIMARY KEY(photo_id)
);

CREATE TABLE blocked (
   user_id INT(11) NOT NULL,
   blocked_id INT(11) NOT NULL
);

INSERT INTO users (name) 
VALUES ('returned'), ('not returned'), ('not returned'), ('not returned');

INSERT INTO photos (user_id) 
VALUES (1), (2);

INSERT INTO blocked (user_id, blocked_id) 
VALUES (4, 2);

以下是我尝试的查询:

SELECT u.*, min(p.photo_id)
FROM users u
INNER JOIN photos p using(user_id)
LEFT JOIN blocked b ON b.user_id = 4 AND b.blocked_id = u.user_id 
WHERE u.user_id != 4
GROUP BY u.user_id
LIMIT 9;

示例数据非常清楚结果应该是什么,因为" name"在此示例中,字段填充"returned", "not returned",仍然返回user-id 2,但是应该通过LEFT JOIN删除它,因为user-id 4在被阻止的被阻止的id字段中具有user-id 2表。

表格

预期结果:

+---------+----------+-----------------+
| user_id |   name   | min(p.photo_id) |
+---------+----------+-----------------+
|       1 | returned |               1 |
+---------+----------+-----------------+
来自查询的

收到结果:

+---------+--------------+-----------------+
| user_id |     name     | min(p.photo_id) |
+---------+--------------+-----------------+
|       1 | returned     |               1 |
|       2 | not returned |               2 |
+---------+--------------+-----------------+

3 个答案:

答案 0 :(得分:1)

我很难回答这个问题,因为我看到你正在比较blocked_id = user_id,尽管在阻止表中你也有一个user_id列。只有你会知道。

但请考虑以下

SELECT u.*, min(p.photo_id),b.*
FROM users u
INNER JOIN photos p using(user_id)
LEFT JOIN blocked b ON b.user_id = 4 AND b.blocked_id = u.user_id 
WHERE u.user_id != 4 and b.user_id is null
GROUP BY u.user_id
LIMIT 9;

+---------+----------+-----------------+---------+------------+
| user_id | name     | min(p.photo_id) | user_id | blocked_id |
+---------+----------+-----------------+---------+------------+
|       1 | returned |               1 |    NULL |       NULL |
+---------+----------+-----------------+---------+------------+

它通过显示添加为第4列和第5列的b。*列来打开声纳。并且稍微混淆where子句。

修改

清理生产

SELECT u.*, min(p.photo_id)
FROM users u
INNER JOIN photos p using(user_id)
LEFT JOIN blocked b ON b.user_id = 4 AND b.blocked_id = u.user_id 
WHERE u.user_id != 4 and b.user_id is null
GROUP BY u.user_id
LIMIT 9;

答案 1 :(得分:0)

我认为您希望WHERE b.blocked_id IS NULL返回未被用户4阻止的用户

答案 2 :(得分:-1)

你可以试试这个......

SELECT u.*, min(p.photo_id)
FROM users u
INNER JOIN photos p using(user_id)
LEFT JOIN blocked b ON b.blocked_id = u.user_id 
GROUP BY u.user_id having min(p.photo_id)<=all(select min(p.photo_id) FROM users u
INNER JOIN photos p using(user_id)
LEFT JOIN blocked b ON b.blocked_id = u.user_id 
GROUP BY u.user_id)
;