INNER JOIN + LEFT JOIN(双重过滤)
INNER JOIN + LEFT JOIN (Double filtering)
我正在尝试过滤我的 table,其中用户在一个 table 中有一行,而在另一个中没有一行。这是我的 table 结构:
下面是 SQL Fiddle: 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 删除,因为用户 ID 4 在被阻止的 table 的 blocked-id 字段中有用户 ID 2。
预期 结果来自 table:
+---------+----------+-----------------+
| user_id | name | min(p.photo_id) |
+---------+----------+-----------------+
| 1 | returned | 1 |
+---------+----------+-----------------+
已收到 个查询结果:
+---------+--------------+-----------------+
| user_id | name | min(p.photo_id) |
+---------+--------------+-----------------+
| 1 | returned | 1 |
| 2 | not returned | 2 |
+---------+--------------+-----------------+
很难回答这个问题,因为我看到您正在比较 blocked_id=user_id,尽管在已屏蔽的 table 中您也有一个 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;
我认为您希望 WHERE b.blocked_id IS NULL
至 return 未被用户 4
阻止的用户
你可以试试这个..
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)
;
我正在尝试过滤我的 table,其中用户在一个 table 中有一行,而在另一个中没有一行。这是我的 table 结构:
下面是 SQL Fiddle: 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 删除,因为用户 ID 4 在被阻止的 table 的 blocked-id 字段中有用户 ID 2。
预期 结果来自 table:
+---------+----------+-----------------+
| user_id | name | min(p.photo_id) |
+---------+----------+-----------------+
| 1 | returned | 1 |
+---------+----------+-----------------+
已收到 个查询结果:
+---------+--------------+-----------------+
| user_id | name | min(p.photo_id) |
+---------+--------------+-----------------+
| 1 | returned | 1 |
| 2 | not returned | 2 |
+---------+--------------+-----------------+
很难回答这个问题,因为我看到您正在比较 blocked_id=user_id,尽管在已屏蔽的 table 中您也有一个 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;
我认为您希望 WHERE b.blocked_id IS NULL
至 return 未被用户 4
你可以试试这个..
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)
;