有没有写SQL语句的过来看个问题

MySql 码拜 8年前 (2016-02-06) 870次浏览
话不多说直接上图
有没有写SQL语句的过来看个问题
如图所示,要求:
1.查询出每个用户的当天的最新两条记录
2.假如有个用户的当天记录中status_other = 1的数量为1,则显示这个用户的最新一条记录
3.假如有个用户的当天记录中status_other = 1的数量大于等于2,则不显示这个用户

SET FOREIGN_KEY_CHECKS=0;
-- --
-- Table structure for record
-- --
DROP TABLE IF EXISTS `record`;
CREATE TABLE `record` (
  `id` int(3) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` varchar(30) NOT NULL,
  `status` int(1) unsigned NOT NULL,
  `status_other` int(1) unsigned NOT NULL,
  `message` varchar(255) DEFAULT NULL,
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
-- --
-- Records of record
-- --
INSERT INTO `record` VALUES ("1", "user1", "1", "0", "用户1失败了,而且没有人管", "2016-05-10 15:40:28");
INSERT INTO `record` VALUES ("2", "user1", "1", "0", "用户1失败了,而且没有人管", "2016-05-10 16:22:34");
INSERT INTO `record` VALUES ("3", "user1", "1", "0", "用户1失败了,而且没有人管", "2016-05-10 16:40:41");
INSERT INTO `record` VALUES ("4", "user2", "1", "0", "用户2失败了,而且没有人管", "2016-05-10 16:42:45");
INSERT INTO `record` VALUES ("5", "user2", "1", "0", "用户2失败了,而且没有人管", "2016-05-10 16:43:07");
INSERT INTO `record` VALUES ("6", "user2", "1", "1", "用户2失败了,但是有人管", "2016-05-10 16:43:33");
INSERT INTO `record` VALUES ("7", "user3", "1", "0", "用户3失败了,而且没有人管", "2016-05-10 16:44:06");
INSERT INTO `record` VALUES ("8", "user3", "1", "1", "用户3失败了,但是有人管", "2016-05-10 16:44:15");
INSERT INTO `record` VALUES ("9", "user3", "1", "1", "用户3失败了,但是有人管", "2016-05-10 16:44:24");
INSERT INTO `record` VALUES ("10", "user3", "1", "0", "用户3失败了,而且没有人管", "2016-05-10 17:57:02");

按照上面要求,应该显示的结果就是蓝色框出来的记录,目前本人只完成了1、3两个要求

SELECT
	a.user_id,
	a.message,
	a.status_other,
	a.create_time
FROM
	record a
WHERE
	-- 排除status_other=1大于等于两条记录
	a.user_id NOT IN (
		SELECT
			c.user_id
		FROM
			(
				SELECT
					b.user_id,
					count(*) AS num
				FROM
					record b
				WHERE
					b.status_other = 1
				GROUP BY
					b.user_id
				HAVING
					num >= 2
			) c
	) 
-- 查询最新的两条记录
AND 2 > (
	SELECT
		count(*)
	FROM
		record b
	WHERE
		a.user_id = b.user_id
	AND a.create_time < b.create_time
)

怎么限制第二步要求啊,求高手帮忙

解决方案

50

引用 7 楼 Hd_vip 的回复:
Quote: 引用 6 楼 yupeigu 的回复:
Quote: 引用 4 楼 Hd_vip 的回复:
Quote: 引用 3 楼 yupeigu 的回复:

本人写了一个完整过滤的,你试试,应该可以了:

select *
from 
(
SELECT
	a.user_id,
	a.message,
	a.status_other,
	a.create_time,
	(select count(*) from record aa where aa.user_id = a.user_id and aa.create_time >=a.create_time) as rn
FROM record a
)a
inner join
(
select user_id,count(case when status_other = "1" then 1 end) c1
from record a
group by user_id
having c1 <=1 
)aa
on a.user_id = aa.user_id
where a.rn <=2

有没有写SQL语句的过来看个问题

这个结果不对吧!应该用户1显示出来2条最新的,用户2显示出来1条最新的

那就改一下呗:

select *
from 
(
SELECT
	a.user_id,
	a.message,
	a.status_other,
	a.create_time,
	(select count(*) from record aa where aa.user_id = a.user_id and aa.create_time >=a.create_time) as rn
FROM record a
)a
inner join
(
select user_id,count(case when status_other = "1" then 1 end) c1
from record a
group by user_id
having c1 <=1 
)aa
on a.user_id = aa.user_id
where a.rn <=2-aa.c1

本人理解了你sql语句的思路了,但是你这sql存在个问题——总是展现rn=1的数据,而忽略了rn=1时status_other的状态,例如本人插入一条user_id = user1并且status_other=1的数据,那么会把这条数据展现出来
有没有写SQL语句的过来看个问题
应该展现的是绿色框中的user1数据,本人想在你的sql基础上改进一下,但是尝试了半天都没成功,你再看一下

这个要看你的实际需求,假如你根本不想要显示出 status_other=1的数据,那就直接过滤吧,相似这样;

select *
from 
(
SELECT
	a.user_id,
	a.message,
	a.status_other,
	a.create_time,
	(select count(*) from record aa where aa.user_id = a.user_id and aa.create_time >=a.create_time and aa.status_other= "0") as rn
FROM record a
where status_other= "0"
)a
inner join
(
select user_id,count(case when status_other = "1" then 1 end) c1
from record a
group by user_id
having c1 <=1 
)aa
on a.user_id = aa.user_id
where a.rn <=2-aa.c1

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明有没有写SQL语句的过来看个问题
喜欢 (0)
[1034331897@qq.com]
分享 (0)