SQL 三天连续问题

建表

DROP TABLE IF EXISTS `exam_record`;
CREATE TABLE `exam_record`  (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '鑷ID',
  `uid` int NOT NULL COMMENT '鐢ㄦ埛ID',
  `exam_id` int NOT NULL COMMENT '璇曞嵎ID',
  `start_time` datetime(0) NOT NULL COMMENT '寮€濮嬫椂闂?,
  `score` tinyint NULL DEFAULT NULL COMMENT '寰楀垎',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

插入值

INSERT INTO `exam_record` VALUES (1, 1001, 9001, '2021-07-02 09:01:01', 80);
INSERT INTO `exam_record` VALUES (2, 1002, 9001, '2021-09-05 19:01:01', 81);
INSERT INTO `exam_record` VALUES (3, 1002, 9002, '2021-09-02 12:01:01', NULL);
INSERT INTO `exam_record` VALUES (4, 1002, 9003, '2021-09-01 12:11:01', NULL);
INSERT INTO `exam_record` VALUES (5, 1002, 9001, '2021-07-02 19:01:01', 82);
INSERT INTO `exam_record` VALUES (6, 1002, 9002, '2021-07-05 18:01:01', 70);
INSERT INTO `exam_record` VALUES (7, 1003, 9002, '2021-07-06 12:01:01', 70);
INSERT INTO `exam_record` VALUES (8, 1003, 9003, '2021-09-07 10:01:01', 90);
INSERT INTO `exam_record` VALUES (9, 1003, 9003, '2021-09-06 12:01:01', 70);
INSERT INTO `exam_record` VALUES (10, 1002, 9003, '2021-09-03 12:01:01', 81);
INSERT INTO `exam_record` VALUES (11, 1005, 9001, '2021-09-01 12:01:01', 88);
INSERT INTO `exam_record` VALUES (12, 1005, 9002, '2021-09-01 12:01:01', 88);
INSERT INTO `exam_record` VALUES (13, 1005, 9002, '2021-09-02 12:11:01', 88);
INSERT INTO `exam_record` VALUES (14, 1005, 9002, '2021-09-03 12:01:01', 86);
INSERT INTO `exam_record` VALUES (15, 1005, 9002, '2021-09-04 12:11:01', 88);

连续登录三天法1

SELECT
	e1.uid,
	DATE( e1.start_time ) AS date1,
	DATE( e2.start_time ) AS date2,
	DATE( e3.start_time ) AS date3 
FROM
	exam_record e1
	LEFT JOIN exam_record e2 ON e1.uid = e2.uid
	LEFT JOIN exam_record e3 ON e2.uid = e3.uid 
WHERE
	DATE( e1.start_time )= DATE( e2.start_time )+ 1 
	AND DATE( e2.start_time )= DATE( e3.start_time )+1

连续登录三天法2

  • 步骤1
SELECT
	uid,
	start_time,
	rank1,
	DATE_SUB( start_time, INTERVAL e1.rank1 DAY ) datesub ,
	DATE(DATE_SUB( start_time, INTERVAL e1.rank1 DAY ) )datesub1 
FROM
	( SELECT uid, start_time, ROW_NUMBER() over ( PARTITION BY uid ORDER BY start_time ) AS rank1 FROM exam_record ) e1
	
	

  • 步骤2
	
SELECT
	uid,
	DATE_SUB( start_time, INTERVAL e1.rank1 DAY ) AS datesub,
	COUNT( 1 ) over ( PARTITION BY uid, DATE_SUB( start_time, INTERVAL e1.rank1 DAY ) ) datesub1,
	COUNT( 1 ) over ( PARTITION BY uid, date( DATE_SUB( start_time, INTERVAL e1.rank1 DAY )) ) date
FROM
	( SELECT uid, start_time, ROW_NUMBER() over ( PARTITION BY uid ORDER BY start_time ) AS rank1 FROM exam_record ) e1
	
  • 汇总代码:
SELECT
	uid
FROM
	( SELECT uid, start_time, ROW_NUMBER() over ( PARTITION BY uid ORDER BY start_time ) AS rank1 FROM exam_record ) e1 
GROUP BY
	uid,
	DATE(DATE_SUB( start_time, INTERVAL e1.rank1 DAY ) )
HAVING
	COUNT(uid)>=3

连续出现3次的Score法1

SELECT
	e1.score 
FROM
	exam_record e1
	LEFT JOIN exam_record e2 ON e1.score = e2.score
	LEFT JOIN exam_record e3 ON e2.score = e3.score 
WHERE
	e2.id = e1.id + 1 
	AND e3.id = e2.id + 1 
	AND e1.score = e2.score 
	AND e2.score = e3.score

连续出现3次的Score法2

此处必须用inner 否则会出现空值相等计入的情况

SELECT
	e1.score 
FROM
	exam_record e1
	INNER JOIN exam_record e2 ON e1.score = e2.score 
	AND e1.id = e2.id - 1
	INNER JOIN exam_record e3 ON e2.score = e3.score 
	AND e2.id = e3.id -1

连续出现3次的Score法3

SELECT
	e1.score 
FROM
	(
	SELECT
		score,
		LEAD( score, 1 ) over ( ORDER BY id ) score1,
		LEAD( score, 2 ) over ( ORDER BY id ) score2 
	FROM
		exam_record 
	) e1 
WHERE
	e1.score = e1.score1 
	AND e1.score = e1.score2

连续出现3次的Score法4

  • 步骤1
SELECT
	id,
	score,
	ROW_NUMBER() over ( ORDER BY id ) AS id1,
	ROW_NUMBER() over ( PARTITION BY score ORDER BY id ) AS score1,
	ROW_NUMBER() over ( ORDER BY id )- ROW_NUMBER() over ( PARTITION BY score ORDER BY id ) AS cha 
FROM
	exam_record
  • 步骤2
SELECT score from (
SELECT
	id,
	score,
	ROW_NUMBER() over ( ORDER BY id ) AS id1,
	ROW_NUMBER() over ( PARTITION BY score ORDER BY id ) AS score1,
	ROW_NUMBER() over ( ORDER BY id )- ROW_NUMBER() over ( PARTITION BY score ORDER BY id ) AS cha 
FROM
	exam_record) e1
GROUP BY score,cha
HAVING COUNT(cha)>=3

连续三天访问且分数大于85的用户

SELECT DISTINCT
	uid,
	start_time,
	score 
FROM
	(
	SELECT
		uid,
		start_time,
		score,
		Lag( score, 2 ) over ( ORDER BY uid ) AS pprvPeople,
		Lag( score, 1 ) over ( ORDER BY uid ) AS prvPeople,
		Lead( score, 1 ) over ( ORDER BY uid ) AS nextPeople,
		Lead( score, 2 ) over ( ORDER BY uid ) AS nnextPeople 
	FROM
		exam_record 
	) e2 
WHERE
	( score >= 80 AND prvPeople >= 80 AND pprvPeople >= 80 ) 
	OR ( score >= 80 AND nextPeople >= 80 AND nnextPeople >= 80 ) 
	OR (score >= 80 AND nextPeople >= 80 AND prvPeople >= 80 
	)

猜你喜欢

转载自blog.csdn.net/weixin_44964850/article/details/129744023