我正在尝试使用从(users_status表)中的数据派生的条件过滤掉我的(用户表)数据。
用户表是一个包含用户ID和用户名
的表CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(25),
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
组表是一个包含组ID的表
CREATE TABLE `groups` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(25),
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
user_status 表是一个包含活动日志的表。它的工作方式是当用户处于组时,用户可以在“开启”或“关闭”之间切换“已添加书签”。
CREATE TABLE `user_status` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`group_id` int(10) unsigned,
`user_id` int(10) unsigned,
`bookmarked` enum('on', 'off'),
`date` datetime,
PRIMARY KEY (`id`),
CONSTRAINT `group_id` FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`) ON DELETE CASCADE,
CONSTRAINT `user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB;
现在我要做的是检索 user_status 中没有条目的所有用户,或者user_status中的最后一个条目“off”
我有一个不完整的子查询的SQL小提琴我尝试这样做,但我没有得到这个工作。 http://sqlfiddle.com/#!2/2d5b4/2
select us.id, us.group_id, g.name as GROUP_NAME, us.user_id, u.username as USER_USERNAME, us.bookmarked, us.date
from user_status us
inner join users u ON u.id = us.user_id
inner join groups g ON g.id = us.group_id
where 'on' != (
select bookmarked
from user_status
group by (group_id, user_id)
where group_id = us.group_id AND user_id = us.user_id
order by ID DESC
limit 1;
);
编辑下午6:28 所以给定 user_status
select * from user_status order by group_id, user_id, date;
+----+----------+---------+------------+--------------------------------+
| ID | GROUP_ID | USER_ID | BOOKMARKED | DATE |
+----+----------+---------+------------+--------------------------------+
| 1 | 1 | 1 | on | January, 16 2014 00:00:00+0000 |
| 2 | 1 | 1 | off | January, 17 2014 00:00:00+0000 |
| 3 | 1 | 1 | on | January, 18 2014 00:00:00+0000 |
| 9 | 1 | 1 | on | January, 18 2014 00:00:00+0000 |
| 7 | 1 | 2 | on | January, 16 2014 00:00:00+0000 |
| 8 | 1 | 2 | off | January, 17 2014 00:00:00+0000 |
| 4 | 2 | 1 | on | January, 16 2013 00:00:00+0000 |
| 5 | 2 | 1 | off | January, 17 2013 00:00:00+0000 |
| 6 | 2 | 1 | on | January, 18 2013 00:00:00+0000 |
+----+----------+---------+------------+--------------------------------+
我希望
group_id(1)user_id(1) 未返回,因为上一个书签是'on'
group_id(1)user_id(2) 返回,因为最后一个书签是“关闭”
group_id(2)user_id(1) 未返回,因为上一个书签是'on'
user_id(3) 返回,因为user_status中没有 注意:原始的sql小提琴示例中没有添加user_id 3
答案 0 :(得分:1)
1-您在group by
子句之前使用WHERE
2-您在子查询中按两列进行分组,而您应按一列分组
尝试这个有效的查询
select us.id, us.group_id, g.name as GROUP_NAME, us.user_id, u.username as USER_USERNAME, us.bookmarked, us.date
from user_status us
inner join users u ON u.id = us.user_id
inner join groups g ON g.id = us.group_id
where 'on' != (
select bookmarked
from user_status
where group_id = us.group_id AND user_id = us.user_id
group by (group_id) --->// you can choose to group by user_id or this.
order by ID DESC
limit 1
);
答案 1 :(得分:1)
我尝试过滤连接,因为这比具有大数据集的子查询要好得多:
SELECT DISTINCT
groups.id AS groupid,
users.id AS userid,
groups.name AS groupname
FROM user_status
INNER JOIN users ON user_status.user_id=users.id
INNER JOIN groups ON user_status.group_id=groups.id
LEFT JOIN
(SELECT
user_id,
group_id,
MAX(`date`) AS maxondate
FROM user_status
WHERE bookmarked='on'
GROUP BY user_id, group_id
) AS ondate ON ondate.group_id=groups.id AND ondate.user_id=users.id
LEFT JOIN
(SELECT
user_id,
group_id,
MAX(`date`) AS maxoffdate
FROM user_status
WHERE bookmarked='off'
GROUP BY user_id, group_id
) AS offdate ON offdate.group_id=groups.id AND offdate.user_id=users.id
WHERE
maxondate IS NULL
OR (
maxondate IS NOT NULL
AND maxoffdate IS NOT NULL
AND maxondate<maxoffdate
)
答案 2 :(得分:1)
试试这个例子sqlfiddle:
SELECT us.id, us.group_id, g.name AS GROUP_NAME, u.id AS user_id, u.username AS USER_USERNAME, us.bookmarked, us.date
FROM users u
LEFT OUTER JOIN user_status us ON u.id = us.user_id AND us.bookmarked = 'off'
LEFT OUTER JOIN groups g ON g.id = us.group_id
WHERE us.date = (SELECT max(ss.date) FROM user_status ss WHERE ss.user_id = us.user_id)
OR NOT EXISTS (SELECT 1 FROM user_status ss WHERE ss.user_id = u.id)
答案 3 :(得分:1)
以下假设用户可以同时为不同的群组设置不同的书签状态。
找到每个(user_id,group_id)组合的最新日期,然后找到与其对应的记录。
根据'off'
子句的规定,书签必须为NULL
或WHERE
。
由于使用user_group
,LEFT JOIN
中没有记录的用户可能会被退回。
SELECT
u.*,
g.*,
us.*
FROM
users AS u
LEFT JOIN
(
SELECT user_id, group_id, MAX(date) AS date
FROM user_status
GROUP BY user_id, group_id
)
AS us_newest
ON us_newest.user_id = u.id
LEFT JOIN
user_status AS us
ON us.user_id = us_newest.user_id
AND us.group_id = us_newest.group_id
AND us.date = us_newest.date
LEFT JOIN
groups AS g
ON g.id = us.group_id
WHERE
us.bookmarked = 'off'
OR us.bookmarked IS NULL
;