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

HaydnSyx 发布于 2016/05/12 16:17
阅读 580
收藏 0

话不多说直接上图

如图所示,要求:
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');



按照上面要求,应该显示的结果就是蓝色框出来的记录,,求大神帮忙

加载中
0
尚浩宇
尚浩宇
骚年,为何要做伸手党
0
H
HaydnSyx

引用来自“尚浩宇”的评论

骚年,为何要做伸手党
我写了一个,但是太麻烦了,没贴出来的原因就是因为我怕我写的限制了其他人的思路,你可以去csdn看我的答案http://bbs.csdn.net/topics/391950019
H
HaydnSyx
回复 @尚浩宇 : 哇,兄台,你这也太给力了!等你写出来一定要交流交流,小弟我没正式学过sql方面的知识,只能停留在使用基本的增删改查,一些高级语句都不会用,所以想问一下看看大家的思路
尚浩宇
尚浩宇
回复 @HaydnSyx : 学习倒不至于,看到你说的业务,手痒,想写,正在装mysql,win10系统之前装没装上就不管了,因为公司都是公共库,没弄本地,
H
HaydnSyx
回复 @尚浩宇 : 这个不用考虑性能之类,因为这里首先只截取当天的数据,然后一般在这表里产生的数据不多,所以不存在大数据的问题。话说,你有没有好的sql,学习一下
尚浩宇
尚浩宇
你这个业务逻辑,可能写出来的sql不会很简单,最终会是一大长断sql,有没有考虑过性能的问题?当数据超过2000万条的时候,性能低下怎么优化?
0
魔力猫
魔力猫
先考虑一下重新写结构吧。表结构冗余了。
魔力猫
魔力猫
回复 @HaydnSyx : 商业数据库窗口函数很容易。用MySQL怎么模拟这种函数,我暂时不知道。
H
HaydnSyx
这个表是我根据实际表模拟精简的一个小表,结构是肯定不能重构的,毕竟这都是很老的表,凑合着用吧
0
色魔张大妈
色魔张大妈
加个计数表
0
h
huyet
user2 筛选后应该是id=6那条?(规则2)
H
HaydnSyx
不是,是id=5的,抱歉,规则写的不太详细。status_other=1的是记录是永远不展示的
0
tomczhen
tomczhen
本来想说用开窗函数的,结果搜了一下 mysql 没有开窗函数
0
朱宏青
朱宏青
SELECT R2.*
FROM 
(SELECT "user_id",SUM("status_other") AS "status_sum",MAX("create_time") AS "create_time_max"
FROM RECORD 
GROUP BY "user_id"
HAVING SUM("status_other") <= 1
) "R1" LEFT JOIN  RECORD R2 ON R1."user_id" = R2."user_id"
WHERE 
R2."create_time" <= (DECODE(R1."status_sum",1,
(SELECT MAX("create_time") FROM RECORD WHERE "status_other" = 0 AND "user_id" = R1."user_id"),
R1."create_time_max"))
AND R2."create_time" >= (DECODE(R1."status_sum",1,
(SELECT MAX("create_time") FROM RECORD WHERE "status_other" = 0 AND "user_id" = R1."user_id"),
(SELECT MAX("create_time") FROM RECORD WHERE "create_time" != R1."create_time_max" AND "user_id"= R2."user_id")
))


本来不用如此冗余的 后来重新看了下要求 发现第2条描述里有坑 果断被坑了 

懒的改了 就这样吧

0
李永china
李永china

select * from record where (select count(status_other) from record where status_other=1 group by user_id)<2 order by time limit 0,1;

没检测 不知对不对 你试一下

0
这个昵称应该没有人用
这个昵称应该没有人用
SELECT *
  FROM (
  --分组排序,ORACLE里的方法,没有试过MYSQL行不行,不行的话可以寻找一下有没有相关的方法,其结果是每个用户按时间倒序并且每个用户都有从1开始的RN编号
  SELECT ROW_NUMBER() OVER(PARTITION BY R.USER_ID ORDER BY R.CREATE_TIME DESC) RN,
               R.*
          FROM TMP_RECORD R
         WHERE TO_CHAR(CREATE_TIME, 'YYYY-MM-DD') = '2016-01-01') T,
       --统计每个USERID对应的STATUS_OTHER,根据其求和结果,生成关联用的字符串,'1,2'表示显示最近两条,'1'表示只显示最新的,''表示不显示
       (SELECT USER_ID, DECODE(SUM(STATUS_OTHER), 0, '1,2', 1, '1', '') TAG
          FROM TMP_RECORD
         WHERE TO_CHAR(CREATE_TIME, 'YYYY-MM-DD') = '2016-01-01'
         GROUP BY USER_ID) F
 WHERE T.USER_ID = F.USER_ID
   AND INSTR(F.TAG, TO_CHAR(T.RN)) > 0

0
H
HaydnSyx

目前看到的最好的答案是在CSDN上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 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



点击查看
返回顶部
顶部