--- title: SQL常è§é¢è¯é¢æ»ç»ï¼4ï¼ category: æ°æ®åº tag: - æ°æ®åºåºç¡ - SQL --- > é¢ç®æ¥æºäºï¼[ç客é¢é¸ - SQL è¿é¶ææ](https://www.nowcoder.com/exam/oj?page=1&tab=SQL%E7%AF%87&topicId=240) è¾é¾æè å°é¾çé¢ç®å¯ä»¥æ ¹æ®èªèº«å®é æ åµåé¢è¯éè¦æ¥å³å®æ¯å¦è¦è·³è¿ã ## ä¸ç¨çªå£å½æ° MySQL 8.0 çæ¬å¼å ¥äºçªå£å½æ°çæ¯æï¼ä¸é¢æ¯ MySQL ä¸å¸¸è§ççªå£å½æ°åå ¶ç¨æ³ï¼ 1. `ROW_NUMBER()`: 为æ¥è¯¢ç»æéä¸çæ¯ä¸è¡åé ä¸ä¸ªå¯ä¸çæ´æ°å¼ã ```sql SELECT col1, col2, ROW_NUMBER() OVER (ORDER BY col1) AS row_num FROM table; ``` 2. `RANK()`: è®¡ç®æ¯ä¸è¡å¨æåºç»æä¸çæåã ```sql SELECT col1, col2, RANK() OVER (ORDER BY col1 DESC) AS ranking FROM table; ``` 3. `DENSE_RANK()`: è®¡ç®æ¯ä¸è¡å¨æåºç»æä¸çæåï¼ä¿çç¸åçæåã ```sql SELECT col1, col2, DENSE_RANK() OVER (ORDER BY col1 DESC) AS ranking FROM table; ``` 4. `NTILE(n)`: å°ç»æåæ n ä¸ªåºæ¬ååçæ¡¶ï¼å¹¶ä¸ºæ¯ä¸ªæ¡¶åé ä¸ä¸ªæ è¯å·ã ```sql SELECT col1, col2, NTILE(4) OVER (ORDER BY col1) AS bucket FROM table; ``` 5. `SUM()`, `AVG()`,`COUNT()`, `MIN()`, `MAX()`: è¿äºèå彿°ä¹å¯ä»¥ä¸çªå£å½æ°ç»å使ç¨ï¼è®¡ç®çªå£å æå®åçæ±æ»ãå¹³åå¼ã计æ°ãæå°å¼åæå¤§å¼ã ```sql SELECT col1, col2, SUM(col1) OVER () AS sum_col FROM table; ``` 6. `LEAD()` å `LAG()`: LEAD 彿°ç¨äºè·åå½åè¡ä¹åçæä¸ªåç§»éçè¡çå¼ï¼è LAG 彿°ç¨äºè·åå½åè¡ä¹åçæä¸ªåç§»éçè¡çå¼ã ```sql SELECT col1, col2, LEAD(col1, 1) OVER (ORDER BY col1) AS next_col1, LAG(col1, 1) OVER (ORDER BY col1) AS prev_col1 FROM table; ``` 7. `FIRST_VALUE()` å `LAST_VALUE()`: FIRST_VALUE 彿°ç¨äºè·åçªå£å æå®åç第ä¸ä¸ªå¼ï¼LAST_VALUE 彿°ç¨äºè·åçªå£å æå®åçæåä¸ä¸ªå¼ã ```sql SELECT col1, col2, FIRST_VALUE(col2) OVER (PARTITION BY col1 ORDER BY col2) AS first_val, LAST_VALUE(col2) OVER (PARTITION BY col1 ORDER BY col2) AS last_val FROM table; ``` çªå£å½æ°é常éè¦é å OVER åå¥ä¸èµ·ä½¿ç¨ï¼ç¨äºå®ä¹çªå£ç大å°ãæåºè§åååç»æ¹å¼ã ### æ¯ç±»è¯å·å¾ååä¸å **æè¿°**ï¼ ç°æè¯å·ä¿¡æ¯è¡¨ `examination_info`ï¼`exam_id` è¯å· ID, `tag` è¯å·ç±»å«, `difficulty` è¯å·é¾åº¦, `duration` èè¯æ¶é¿, `release_time` å叿¶é´ï¼ï¼ | id | exam_id | tag | difficulty | duration | release_time | | ---- | ------- | ---- | ---------- | -------- | ------------------- | | 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 | | 2 | 9002 | SQL | hard | 60 | 2021-09-01 06:00:00 | | 3 | 9003 | ç®æ³ | medium | 80 | 2021-09-01 10:00:00 | è¯å·ä½çè®°å½è¡¨ `exam_record`ï¼`uid` ç¨æ· ID, `exam_id` è¯å· ID, `start_time` å¼å§ä½çæ¶é´, `submit_time` äº¤å·æ¶é´, score å¾åï¼ï¼ | id | uid | exam_id | start_time | submit_time | score | | ---- | ---- | ------- | ------------------- | ------------------- | ------ | | 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 78 | | 2 | 1002 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 81 | | 3 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81 | | 4 | 1003 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:40:01 | 86 | | 5 | 1003 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:51 | 89 | | 6 | 1004 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:30:01 | 85 | | 7 | 1005 | 9003 | 2021-09-01 12:01:01 | 2021-09-01 12:31:02 | 85 | | 8 | 1006 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:21:01 | 84 | | 9 | 1003 | 9003 | 2021-09-08 12:01:01 | 2021-09-08 12:11:01 | 40 | | 10 | 1003 | 9002 | 2021-09-01 14:01:01 | (NULL) | (NULL) | æ¾å°æ¯ç±»è¯å·å¾åçå 3 åï¼å¦æä¸¤äººæå¤§åæ°ç¸åï¼éæ©æå°åæ°å¤§è ï¼å¦æè¿ç¸åï¼éæ© uid 大è ãç±ç¤ºä¾æ°æ®ç»æè¾åºå¦ä¸ï¼ | tid | uid | ranking | | ---- | ---- | ------- | | SQL | 1003 | 1 | | SQL | 1004 | 2 | | SQL | 1002 | 3 | | ç®æ³ | 1005 | 1 | | ç®æ³ | 1006 | 2 | | ç®æ³ | 1003 | 3 | **è§£é**ï¼æä½çå¾åè®°å½çè¯å· tag æ SQL åç®æ³ï¼SQL è¯å·ç¨æ· 1001ã1002ã1003ã1004 æä½çå¾åï¼æé«å¾ååå«ä¸º 81ã81ã89ã85ï¼æä½å¾ååå«ä¸º 78ã81ã86ã40ï¼å æ¤å ææé«å¾åæååææä½å¾åæåååä¸ä¸º 1003ã1004ã1002ã **çæ¡**ï¼ ```sql SELECT tag, UID, ranking FROM (SELECT b.tag AS tag, a.uid AS UID, ROW_NUMBER() OVER (PARTITION BY b.tag ORDER BY b.tag, max(a.score) DESC, min(a.score) DESC, a.uid DESC) AS ranking FROM exam_record a LEFT JOIN examination_info b ON a.exam_id = b.exam_id GROUP BY b.tag, a.uid) t WHERE ranking <= 3 ``` ### 第äºå¿«/æ ¢ç¨æ¶ä¹å·®å¤§äºè¯å·æ¶é¿ä¸åçè¯å·ï¼è¾é¾ï¼ **æè¿°**ï¼ ç°æè¯å·ä¿¡æ¯è¡¨ `examination_info`ï¼`exam_id` è¯å· ID, `tag` è¯å·ç±»å«, `difficulty` è¯å·é¾åº¦, `duration` èè¯æ¶é¿, `release_time` å叿¶é´ï¼ï¼ | id | exam_id | tag | difficulty | duration | release_time | | ---- | ------- | ---- | ---------- | -------- | ------------------- | | 1 | 9001 | SQL | hard | 60 | 2021-09-01 06:00:00 | | 2 | 9002 | C++ | hard | 60 | 2021-09-01 06:00:00 | | 3 | 9003 | ç®æ³ | medium | 80 | 2021-09-01 10:00:00 | è¯å·ä½çè®°å½è¡¨ `exam_record`ï¼`uid` ç¨æ· ID, `exam_id` è¯å· ID, `start_time` å¼å§ä½çæ¶é´, `submit_time` äº¤å·æ¶é´, `score` å¾åï¼ï¼ | id | uid | exam_id | start_time | submit_time | score | | ---- | ---- | ------- | ------------------- | ------------------- | ------ | | 1 | 1001 | 9001 | 2021-09-01 09:01:01 | 2021-09-01 09:51:01 | 78 | | 2 | 1001 | 9002 | 2021-09-01 09:01:01 | 2021-09-01 09:31:00 | 81 | | 3 | 1002 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:01 | 81 | | 4 | 1003 | 9001 | 2021-09-01 19:01:01 | 2021-09-01 19:59:01 | 86 | | 5 | 1003 | 9002 | 2021-09-01 12:01:01 | 2021-09-01 12:31:51 | 89 | | 6 | 1004 | 9002 | 2021-09-01 19:01:01 | 2021-09-01 19:30:01 | 85 | | 7 | 1005 | 9001 | 2021-09-01 12:01:01 | 2021-09-01 12:31:02 | 85 | | 8 | 1006 | 9001 | 2021-09-07 10:01:01 | 2021-09-07 10:21:01 | 84 | | 9 | 1003 | 9001 | 2021-09-08 12:01:01 | 2021-09-08 12:11:01 | 40 | | 10 | 1003 | 9002 | 2021-09-01 14:01:01 | (NULL) | (NULL) | | 11 | 1005 | 9001 | 2021-09-01 14:01:01 | (NULL) | (NULL) | | 12 | 1003 | 9003 | 2021-09-08 15:01:01 | (NULL) | (NULL) | æ¾å°ç¬¬äºå¿«åç¬¬äºæ ¢ç¨æ¶ä¹å·®å¤§äºè¯å·æ¶é¿çä¸åçè¯å·ä¿¡æ¯ï¼æè¯å· ID éåºæåºãç±ç¤ºä¾æ°æ®ç»æè¾åºå¦ä¸ï¼ | exam_id | duration | release_time | | ------- | -------- | ------------------- | | 9001 | 60 | 2021-09-01 06:00:00 | **è§£é**ï¼è¯å· 9001 被ä½çç¨æ¶æ 50 åéã50 åéã30 å 1 ç§ã11 åéã10 åéï¼ç¬¬äºå¿«åç¬¬äºæ ¢ç¨æ¶ä¹å·®ä¸º 50 åé-11 åé=39 åéï¼è¯å·æ¶é¿ä¸º 60 åéï¼å æ¤æ»¡è¶³å¤§äºè¯å·æ¶é¿ä¸åçæ¡ä»¶ï¼è¾åºè¯å· IDãæ¶é¿ãå叿¶é´ã **æè·¯ï¼** ç¬¬ä¸æ¥ï¼æ¾å°æ¯å¼ è¯å·å®ææ¶é´çé¡ºåºæååååºæå ä¹å°±æ¯è¡¨ aï¼ ç¬¬äºæ¥ï¼ä¸éè¿è¯å·ä¿¡æ¯è¡¨ b 建ç«å è¿æ¥ï¼å¹¶æ ¹æ®è¯å· id åç»ï¼å©ç¨`having`çéæå为第äºä¸ªæ°æ®ï¼å°ç§è½¬å为åéå¹¶è¿è¡æ¯è¾ï¼æååæ ¹æ®è¯å· id ååºæåºå°±è¡ **çæ¡**ï¼ ```sql SELECT a.exam_id, b.duration, b.release_time FROM (SELECT exam_id, row_number() OVER (PARTITION BY exam_id ORDER BY timestampdiff(SECOND, start_time, submit_time) DESC) rn1, row_number() OVER (PARTITION BY exam_id ORDER BY timestampdiff(SECOND, start_time, submit_time) ASC) rn2, timestampdiff(SECOND, start_time, submit_time) timex FROM exam_record WHERE score IS NOT NULL ) a INNER JOIN examination_info b ON a.exam_id = b.exam_id GROUP BY a.exam_id HAVING (max(IF (rn1 = 2, a.timex, 0))- max(IF (rn2 = 2, a.timex, 0)))/ 60 > b.duration / 2 ORDER BY a.exam_id DESC ``` ### è¿ç»ä¸¤æ¬¡ä½çè¯å·çæå¤§æ¶é´çªï¼è¾é¾ï¼ **æè¿°** ç°æè¯å·ä½çè®°å½è¡¨ `exam_record`ï¼`uid` ç¨æ· ID, `exam_id` è¯å· ID, `start_time` å¼å§ä½çæ¶é´, `submit_time` äº¤å·æ¶é´, `score` å¾åï¼ï¼ | id | uid | exam_id | start_time | submit_time | score | | ---- | ---- | ------- | ------------------- | ------------------- | ----- | | 1 | 1006 | 9003 | 2021-09-07 10:01:01 | 2021-09-07 10:21:02 | 84 | | 2 | 1006 | 9001 | 2021-09-01 12:11:01 | 2021-09-01 12:31:01 | 89 | | 3 | 1006 | 9002 | 2021-09-06 10:01:01 | 2021-09-06 10:21:01 | 81 | | 4 | 1005 | 9002 | 2021-09-05 10:01:01 | 2021-09-05 10:21:01 | 81 | | 5 | 1005 | 9001 | 2021-09-05 10:31:01 | 2021-09-05 10:51:01 | 81 | 请计ç®å¨ 2021 å¹´è³å°æä¸¤å¤©ä½çè¿è¯å·ç人ä¸ï¼è®¡ç®è¯¥å¹´è¿ç»ä¸¤æ¬¡ä½çè¯å·çæå¤§æ¶é´çª `days_window`ï¼é£ä¹æ ¹æ®è¯¥å¹´çåå²è§å¾ä»å¨ `days_window` 天éå¹³åä¼åå¤å°å¥è¯å·ï¼ææå¤§æ¶é´çªåå¹³ååçè¯å·å¥æ°ååºæåºãç±ç¤ºä¾æ°æ®ç»æè¾åºå¦ä¸ï¼ | uid | days_window | avg_exam_cnt | | ---- | ----------- | ------------ | | 1006 | 6 | 2.57 | **è§£é**ï¼ç¨æ· 1006 åå«å¨ 20210901ã20210906ã20210907 ä½çè¿ 3 次è¯å·ï¼è¿ç»ä¸¤æ¬¡ä½çæå¤§æ¶é´çªä¸º 6 天ï¼1 å·å° 6 å·ï¼ï¼ä» 1 å·å° 7 å·è¿ 7 天éå ±åäº 3 å¼ è¯å·ï¼å¹³åæ¯å¤© 3/7=0.428571 å¼ ï¼é£ä¹ 6 天éå¹³åä¼å 0.428571\*6=2.57 å¼ è¯å·ï¼ä¿ç两ä½å°æ°ï¼ï¼ç¨æ· 1005 å¨ 20210905 åäºä¸¤å¼ è¯å·ï¼ä½æ¯åªæä¸å¤©çä½çè®°å½ï¼è¿æ»¤æã **æè·¯ï¼** ä¸é¢è¿ä¸ªè§£éä¸æç¤ºè¦å¯¹ä½çè®°å½å»éï¼åä¸å«è¢«éªäºï¼ä¸è¦å»éï¼å»éå°±éä¸è¿æµè¯ç¨ä¾ã注æéå¶æ¶é´æ¯ 2021 å¹´ï¼ èä¸è¦æ³¨ææ¶é´å·®è¦+1 天ï¼è¿è¦æ³¨æ==没交å·ä¹ç®å¨å ==ï¼ï¼ï¼ï¼ ï¼åæ£æè§è¿é¢æè¿°ä¸æ¸ ï¼åºç䏿¯å¾å¥½ï¼ **çæ¡**ï¼ ```sql SELECT UID, max(datediff(next_time, start_time)) + 1 AS days_window, round(count(start_time)/(datediff(max(start_time), min(start_time))+ 1) * (max(datediff(next_time, start_time))+ 1), 2) AS avg_exam_cnt FROM (SELECT UID, start_time, lead(start_time, 1) OVER (PARTITION BY UID ORDER BY start_time) AS next_time FROM exam_record WHERE YEAR (start_time) = '2021' ) a GROUP BY UID HAVING count(DISTINCT date(start_time)) > 1 ORDER BY days_window DESC, avg_exam_cnt DESC ``` ### è¿ä¸ä¸ªææªå®æä¸º 0 çç¨æ·å®ææ åµ **æè¿°**ï¼ ç°æè¯å·ä½çè®°å½è¡¨ `exam_record`ï¼`uid`:ç¨æ· ID, `exam_id`:è¯å· ID, `start_time`:å¼å§ä½çæ¶é´, `submit_time`:äº¤å·æ¶é´ï¼ä¸ºç©ºçè¯å代表æªå®æ, `score`:å¾åï¼ï¼ | id | uid | exam_id | start_time | submit_time | score | | ---- | ---- | ------- | ------------------- | ------------------- | ------ | | 1 | 1006 | 9003 | 2021-09-06 10:01:01 | 2021-09-06 10:21:02 | 84 | | 2 | 1006 | 9001 | 2021-08-02 12:11:01 | 2021-08-02 12:31:01 | 89 | | 3 | 1006 | 9002 | 2021-06-06 10:01:01 | 2021-06-06 10:21:01 | 81 | | 4 | 1006 | 9002 | 2021-05-06 10:01:01 | 2021-05-06 10:21:01 | 81 | | 5 | 1006 | 9001 | 2021-05-01 12:01:01 | (NULL) | (NULL) | | 6 | 1001 | 9001 | 2021-09-05 10:31:01 | 2021-09-05 10:51:01 | 81 | | 7 | 1001 | 9003 | 2021-08-01 09:01:01 | 2021-08-01 09:51:11 | 78 | | 8 | 1001 | 9002 | 2021-07-01 09:01:01 | 2021-07-01 09:31:00 | 81 | | 9 | 1001 | 9002 | 2021-07-01 12:01:01 | 2021-07-01 12:31:01 | 81 | | 10 | 1001 | 9002 | 2021-07-01 12:01:01 | (NULL) | (NULL) | æ¾å°æ¯ä¸ªäººè¿ä¸ä¸ªæè¯å·ä½çè®°å½çæä»½ä¸æ²¡æè¯å·æ¯æªå®æç¶æçç¨æ·çè¯å·ä½ç宿æ°ï¼æè¯å·å®ææ°åç¨æ· ID éåºæåãç±ç¤ºä¾æ°æ®ç»æè¾åºå¦ä¸ï¼ | uid | exam_complete_cnt | | ---- | ----------------- | | 1006 | 3 | **è§£é**ï¼ç¨æ· 1006 è¿ä¸ä¸ªæä½çè¯å·çæä»½ä¸º 202109ã202108ã202106ï¼ä½çè¯å·æ°ä¸º 3ï¼å ¨é¨å®æï¼ç¨æ· 1001 è¿ä¸ä¸ªæä½çè¯å·çæä»½ä¸º 202109ã202108ã202107ï¼ä½çè¯å·æ°ä¸º 5ï¼å®æè¯å·æ°ä¸º 4ï¼å ä¸ºææªå®æè¯å·ï¼æ è¿æ»¤æã **æè·¯:** 1. `æ¾å°æ¯ä¸ªäººè¿ä¸ä¸ªæè¯å·ä½çè®°å½çæä»½ä¸æ²¡æè¯å·æ¯æªå®æç¶æçç¨æ·çè¯å·ä½ç宿æ°`é¦å çè¿å¥è¯ï¼è¯å®è¦å æ ¹æ®äººè¿è¡åç» 2. æè¿ä¸ä¸ªæï¼å¯ä»¥éç¨è¿ç»é夿åï¼ååºæåï¼æå<=3 3. ç»è®¡ä½çæ° 4. æ¼è£ å©ä½æ¡ä»¶ 5. æåº **çæ¡**ï¼ ```sql SELECT UID, count(score) exam_complete_cnt FROM (SELECT *, DENSE_RANK() OVER (PARTITION BY UID ORDER BY date_format(start_time, '%Y%m') DESC) dr FROM exam_record) t1 WHERE dr <= 3 GROUP BY UID HAVING count(dr)= count(score) ORDER BY exam_complete_cnt DESC, UID DESC ``` ### æªå®æçè¾é«ç 50%ç¨æ·è¿ä¸ä¸ªæçå·æ åµï¼å°é¾ï¼ **æè¿°**ï¼ ç°æç¨æ·ä¿¡æ¯è¡¨ `user_info`ï¼`uid` ç¨æ· IDï¼`nick_name` æµç§°, `achievement` æå°±å¼, `level` ç级, `job` è䏿¹å, `register_time` æ³¨åæ¶é´ï¼ï¼ | id | uid | nick_name | achievement | level | job | register_time | | ---- | ---- | ----------- | ----------- | ----- | ---- | ------------------- | | 1 | 1001 | ç客 1 å· | 3200 | 7 | ç®æ³ | 2020-01-01 10:00:00 | | 2 | 1002 | ç客 2 å· | 2500 | 6 | ç®æ³ | 2020-01-01 10:00:00 | | 3 | 1003 | ç客 3 å· â | 2200 | 5 | ç®æ³ | 2020-01-01 10:00:00 | è¯å·ä¿¡æ¯è¡¨ `examination_info`ï¼`exam_id` è¯å· ID, `tag` è¯å·ç±»å«, `difficulty` è¯å·é¾åº¦, `duration` èè¯æ¶é¿, `release_time` å叿¶é´ï¼ï¼ | id | exam_id | tag | difficulty | duration | release_time | | ---- | ------- | ------ | ---------- | -------- | ------------------- | | 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 | | 2 | 9002 | SQL | hard | 80 | 2020-01-01 10:00:00 | | 3 | 9003 | ç®æ³ | hard | 80 | 2020-01-01 10:00:00 | | 4 | 9004 | PYTHON | medium | 70 | 2020-01-01 10:00:00 | è¯å·ä½çè®°å½è¡¨ `exam_record`ï¼`uid` ç¨æ· ID, `exam_id` è¯å· ID, `start_time` å¼å§ä½çæ¶é´, `submit_time` äº¤å·æ¶é´, `score` å¾åï¼ï¼ | id | uid | exam_id | start_time | submit_time | score | | ---- | ---- | ------- | ------------------- | ------------------- | ----- | | 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 90 | | 15 | 1002 | 9001 | 2020-01-01 18:01:01 | 2020-01-01 18:59:02 | 90 | | 13 | 1001 | 9001 | 2020-01-02 10:01:01 | 2020-01-02 10:31:01 | 89 | | 2 | 1002 | 9001 | 2020-01-20 10:01:01 | | | | 3 | 1002 | 9001 | 2020-02-01 12:11:01 | | | | 5 | 1001 | 9001 | 2020-03-01 12:01:01 | | | | 6 | 1002 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:41:01 | 90 | | 4 | 1003 | 9001 | 2020-03-01 19:01:01 | | | | 7 | 1002 | 9001 | 2020-05-02 19:01:01 | 2020-05-02 19:32:00 | 90 | | 14 | 1001 | 9002 | 2020-01-01 12:11:01 | | | | 8 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:59:01 | 69 | | 9 | 1001 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 | | 10 | 1002 | 9002 | 2020-02-02 12:01:01 | | | | 11 | 1002 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:43:01 | 81 | | 12 | 1002 | 9002 | 2020-03-02 12:11:01 | | | | 17 | 1001 | 9002 | 2020-05-05 18:01:01 | | | | 16 | 1002 | 9003 | 2020-05-06 12:01:01 | | | 请ç»è®¡ SQL è¯å·ä¸æªå®æçè¾é«ç 50%ç¨æ·ä¸ï¼6 级å 7 çº§ç¨æ·å¨æè¯å·ä½çè®°å½çè¿ä¸ä¸ªæä¸ï¼æ¯ä¸ªæççå·æ°ç®å宿æ°ç®ãæç¨æ· IDãæä»½ååºæåºã ç±ç¤ºä¾æ°æ®ç»æè¾åºå¦ä¸ï¼ | uid | start_month | total_cnt | complete_cnt | | ---- | ----------- | --------- | ------------ | | 1002 | 202002 | 3 | 1 | | 1002 | 202003 | 2 | 1 | | 1002 | 202005 | 2 | 1 | è§£éï¼åä¸ªç¨æ·å¯¹ SQL è¯å·çæªå®ææ°ãä½çæ»æ°ãæªå®æçå¦ä¸ï¼ | uid | incomplete_cnt | total_cnt | incomplete_rate | | ---- | -------------- | --------- | --------------- | | 1001 | 3 | 7 | 0.4286 | | 1002 | 4 | 8 | 0.5000 | | 1003 | 1 | 1 | 1.0000 | 1001ã1002ã1003 åå«æå¨ 1.0ã0.5ã0.0 çä½ç½®ï¼å æ¤è¾é«ç 50%ç¨æ·ï¼æä½<=0.5ï¼ä¸º 1002ã1003ï¼ 1003 䏿¯ 6 级æ 7 çº§ï¼ æè¯å·ä½çè®°å½çè¿ä¸ä¸ªæä¸º 202005ã202003ã202002ï¼ è¿ä¸ä¸ªæé 1002 çä½ç颿°åå«ä¸º 3ã2ã2ï¼å®ææ°ç®åå«ä¸º 1ã1ã1ã **æè·¯ï¼** 注æç¹ï¼è¿é¢æ³¨ææ±çæ¯ææçç颿¬¡æ°åå®ææ¬¡æ°ï¼è sql ç±»å«çè¯å·æ¯éå¶æªå®æçæåï¼6, 7 çº§ç¨æ·éå¶çæ¯åé¢è®°å½ã å æ±åºæªå®æççæå ```sql SELECT UID, count(submit_time IS NULL OR NULL)/ count(start_time) AS num, PERCENT_RANK() OVER ( ORDER BY count(submit_time IS NULL OR NULL)/ count(start_time)) AS ranking FROM exam_record LEFT JOIN examination_info USING (exam_id) WHERE tag = 'SQL' GROUP BY UID ``` åæ±åºæè¿ä¸ä¸ªæçç»ä¹ è®°å½ ```sql SELECT UID, date_format(start_time, '%Y%m') AS month_d, submit_time, exam_id, dense_rank() OVER (PARTITION BY UID ORDER BY date_format(start_time, '%Y%m') DESC) AS ranking FROM exam_record LEFT JOIN user_info USING (UID) WHERE LEVEL IN (6,7) ``` **çæ¡**ï¼ ```sql SELECT t1.uid, t1.month_d, count(*) AS total_cnt, count(t1.submit_time) AS complete_cnt FROM-- å æ±åºæªå®æççæå (SELECT UID, count(submit_time IS NULL OR NULL)/ count(start_time) AS num, PERCENT_RANK() OVER ( ORDER BY count(submit_time IS NULL OR NULL)/ count(start_time)) AS ranking FROM exam_record LEFT JOIN examination_info USING (exam_id) WHERE tag = 'SQL' GROUP BY UID) t INNER JOIN (-- åæ±åºè¿ä¸ä¸ªæçç»ä¹ è®°å½ SELECT UID, date_format(start_time, '%Y%m') AS month_d, submit_time, exam_id, dense_rank() OVER (PARTITION BY UID ORDER BY date_format(start_time, '%Y%m') DESC) AS ranking FROM exam_record LEFT JOIN user_info USING (UID) WHERE LEVEL IN (6,7) ) t1 USING (UID) WHERE t1.ranking <= 3 AND t.ranking >= 0.5 -- 使ç¨éå¶æ¾å°ç¬¦åæ¡ä»¶çè®°å½ GROUP BY t1.uid, t1.month_d ORDER BY t1.uid, t1.month_d ``` ### è¯å·å®ææ°åæ¯ 2020 å¹´çå¢é¿çåæåååï¼å°é¾ï¼ **æè¿°**ï¼ ç°æè¯å·ä¿¡æ¯è¡¨ `examination_info`ï¼`exam_id` è¯å· ID, `tag` è¯å·ç±»å«, `difficulty` è¯å·é¾åº¦, `duration` èè¯æ¶é¿, `release_time` å叿¶é´ï¼ï¼ | id | exam_id | tag | difficulty | duration | release_time | | ---- | ------- | ------ | ---------- | -------- | ------------------- | | 1 | 9001 | SQL | hard | 60 | 2021-01-01 10:00:00 | | 2 | 9002 | C++ | hard | 80 | 2021-01-01 10:00:00 | | 3 | 9003 | ç®æ³ | hard | 80 | 2021-01-01 10:00:00 | | 4 | 9004 | PYTHON | medium | 70 | 2021-01-01 10:00:00 | è¯å·ä½çè®°å½è¡¨ `exam_record`ï¼`uid` ç¨æ· ID, `exam_id` è¯å· ID, `start_time` å¼å§ä½çæ¶é´, `submit_time` äº¤å·æ¶é´, `score` å¾åï¼ï¼ | id | uid | exam_id | start_time | submit_time | score | | ---- | ---- | ------- | ------------------- | ------------------- | ----- | | 1 | 1001 | 9001 | 2020-08-02 10:01:01 | 2020-08-02 10:31:01 | 89 | | 2 | 1002 | 9001 | 2020-04-01 18:01:01 | 2020-04-01 18:59:02 | 90 | | 3 | 1001 | 9001 | 2020-04-01 09:01:01 | 2020-04-01 09:21:59 | 80 | | 5 | 1002 | 9001 | 2021-03-02 19:01:01 | 2021-03-02 19:32:00 | 20 | | 8 | 1003 | 9001 | 2021-05-02 12:01:01 | 2021-05-02 12:31:01 | 98 | | 13 | 1003 | 9001 | 2020-01-02 10:01:01 | 2020-01-02 10:31:01 | 89 | | 9 | 1001 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 | | 10 | 1002 | 9002 | 2021-02-02 12:01:01 | 2020-02-02 12:43:01 | 81 | | 11 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:59:01 | 69 | | 16 | 1002 | 9002 | 2020-02-02 12:01:01 | | | | 17 | 1002 | 9002 | 2020-03-02 12:11:01 | | | | 18 | 1001 | 9002 | 2021-05-05 18:01:01 | | | | 4 | 1002 | 9003 | 2021-01-20 10:01:01 | 2021-01-20 10:10:01 | 81 | | 6 | 1001 | 9003 | 2021-04-02 19:01:01 | 2021-04-02 19:40:01 | 89 | | 15 | 1002 | 9003 | 2021-01-01 18:01:01 | 2021-01-01 18:59:02 | 90 | | 7 | 1004 | 9004 | 2020-05-02 12:01:01 | 2020-05-02 12:20:01 | 99 | | 12 | 1001 | 9004 | 2021-09-02 12:11:01 | | | | 14 | 1002 | 9004 | 2020-01-01 12:11:01 | 2020-01-01 12:31:01 | 83 | è¯·è®¡ç® 2021 å¹´ä¸åå¹´åç±»è¯å·çå宿¬¡æ°ç¸æ¯ 2020 å¹´ä¸åå¹´åæçå¢é¿çï¼ç¾åæ¯æ ¼å¼ï¼ä¿ç 1 ä½å°æ°ï¼ï¼ä»¥åå宿¬¡æ°æåååï¼æå¢é¿çå 21 å¹´æåéåºè¾åºã ç±ç¤ºä¾æ°æ®ç»æè¾åºå¦ä¸ï¼ | tag | exam_cnt_20 | exam_cnt_21 | growth_rate | exam_cnt_rank_20 | exam_cnt_rank_21 | rank_delta | | ---- | ----------- | ----------- | ----------- | ---------------- | ---------------- | ---------- | | SQL | 3 | 2 | -33.3% | 1 | 2 | 1 | è§£éï¼2020 å¹´ä¸åå¹´æ 3 个 tag æä½ç宿çè®°å½ï¼å嫿¯ C++ãSQLãPYTHONï¼å®ä»¬è¢«åå®ç次æ°å嫿¯ 3ã3ã2ï¼å宿¬¡æ°æå为 1ã1ï¼å¹¶åï¼ã3ï¼ 2021 å¹´ä¸åå¹´æ 2 个 tag æä½ç宿çè®°å½ï¼å嫿¯ç®æ³ãSQLï¼å®ä»¬è¢«åå®ç次æ°å嫿¯ 3ã2ï¼å宿¬¡æ°æå为 1ã2ï¼å ·ä½å¦ä¸ï¼ | tag | start_year | exam_cnt | exam_cnt_rank | | ------ | ---------- | -------- | ------------- | | C++ | 2020 | 3 | 1 | | SQL | 2020 | 3 | 1 | | PYTHON | 2020 | 2 | 3 | | ç®æ³ | 2021 | 3 | 1 | | SQL | 2021 | 2 | 2 | å æ¤è½è¾åºåæ¯ç»æç tag åªæ SQLï¼ä» 2020 å° 2021 å¹´ï¼å宿¬¡æ° 3=>2ï¼åå° 33.3%ï¼ä¿ç 1 ä½å°æ°ï¼ï¼æå 1=>2ï¼åé 1 åã **æè·¯ï¼** æ¬é¢é¾ç¹å¨äºé¿æ´åçæ°æ®ç±»åè¦æ±ä¸è½æè´å·äº§çï¼ç¨ cast 彿°è½¬æ¢æ°æ®ç±»å为 signedã 以åç¨å°ç`å¢é¿ç计ç®å ¬å¼ï¼(exam_cnt_21-exam_cnt_20)/exam_cnt_20` å宿¬¡æ°æåååï¼2021 å¹´å 2020 å¹´æ¯æååäºæè éäºå¤å°ï¼ 计ç®å ¬å¼ï¼`exam_cnt_rank_21 - exam_cnt_rank_20` å¨ MySQL ä¸ï¼`CAST()` 彿°ç¨äºå°ä¸ä¸ªè¡¨è¾¾å¼çæ°æ®ç±»å转æ¢ä¸ºå¦ä¸ä¸ªæ°æ®ç±»åãå®çåºæ¬è¯æ³å¦ä¸ï¼ ```sql CAST(expression AS data_type) -- å°ä¸ä¸ªåç¬¦ä¸²è½¬æ¢ææ´æ° SELECT CAST('123' AS INT); ``` 示ä¾å°±ä¸ä¸ä¸ä¸¾ä¾äºï¼è¿ä¸ªå½æ°å¾ç®å **çæ¡**ï¼ ```sql SELECT tag, exam_cnt_20, exam_cnt_21, concat( round( 100 * (exam_cnt_21 - exam_cnt_20) / exam_cnt_20, 1 ), '%' ) AS growth_rate, exam_cnt_rank_20, exam_cnt_rank_21, cast(exam_cnt_rank_21 AS signed) - cast(exam_cnt_rank_20 AS signed) AS rank_delta FROM ( #2020å¹´ã2021å¹´ä¸åå¹´åç±»è¯å·çå宿¬¡æ°åå宿¬¡æ°æå SELECT tag, count( IF ( date_format(start_time, '%Y%m%d') BETWEEN '20200101' AND '20200630', start_time, NULL ) ) AS exam_cnt_20, count( IF ( substring(start_time, 1, 10) BETWEEN '2021-01-01' AND '2021-06-30', start_time, NULL ) ) AS exam_cnt_21, rank() over ( ORDER BY count( IF ( date_format(start_time, '%Y%m%d') BETWEEN '20200101' AND '20200630', start_time, NULL ) ) DESC ) AS exam_cnt_rank_20, rank() over ( ORDER BY count( IF ( substring(start_time, 1, 10) BETWEEN '2021-01-01' AND '2021-06-30', start_time, NULL ) ) DESC ) AS exam_cnt_rank_21 FROM examination_info JOIN exam_record USING (exam_id) WHERE submit_time IS NOT NULL GROUP BY tag ) main WHERE exam_cnt_21 * exam_cnt_20 <> 0 ORDER BY growth_rate DESC, exam_cnt_rank_21 DESC ``` ## èåçªå£å½æ° ### 对è¯å·å¾åå min-max å½ä¸å **æè¿°**ï¼ ç°æè¯å·ä¿¡æ¯è¡¨ `examination_info`ï¼`exam_id` è¯å· ID, `tag` è¯å·ç±»å«, `difficulty` è¯å·é¾åº¦, `duration` èè¯æ¶é¿, `release_time` å叿¶é´ï¼ï¼ | id | exam_id | tag | difficulty | duration | release_time | | ---- | ------- | ------ | ---------- | -------- | ------------------- | | 1 | 9001 | SQL | hard | 60 | 2020-01-01 10:00:00 | | 2 | 9002 | C++ | hard | 80 | 2020-01-01 10:00:00 | | 3 | 9003 | ç®æ³ | hard | 80 | 2020-01-01 10:00:00 | | 4 | 9004 | PYTHON | medium | 70 | 2020-01-01 10:00:00 | è¯å·ä½çè®°å½è¡¨ `exam_record`ï¼`uid` ç¨æ· ID, `exam_id` è¯å· ID, `start_time` å¼å§ä½çæ¶é´, `submit_time` äº¤å·æ¶é´, `score` å¾åï¼ï¼ | id | uid | exam_id | start_time | submit_time | score | | ---- | ---- | ------- | ------------------- | ------------------- | ------ | | 6 | 1003 | 9001 | 2020-01-02 12:01:01 | 2020-01-02 12:31:01 | 68 | | 9 | 1001 | 9001 | 2020-01-02 10:01:01 | 2020-01-02 10:31:01 | 89 | | 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 90 | | 12 | 1002 | 9002 | 2021-05-05 18:01:01 | (NULL) | (NULL) | | 3 | 1004 | 9002 | 2020-01-01 12:01:01 | 2020-01-01 12:11:01 | 60 | | 2 | 1003 | 9002 | 2020-01-01 19:01:01 | 2020-01-01 19:30:01 | 75 | | 7 | 1001 | 9002 | 2020-01-02 12:01:01 | 2020-01-02 12:43:01 | 81 | | 10 | 1002 | 9002 | 2020-01-01 12:11:01 | 2020-01-01 12:31:01 | 83 | | 4 | 1003 | 9002 | 2020-01-01 12:01:01 | 2020-01-01 12:41:01 | 90 | | 5 | 1002 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:32:00 | 90 | | 11 | 1002 | 9004 | 2021-09-06 12:01:01 | (NULL) | (NULL) | | 8 | 1001 | 9005 | 2020-01-02 12:11:01 | (NULL) | (NULL) | å¨ç©çå¦åç»è®¡å¦æ°æ®è®¡ç®æ¶ï¼æä¸ªæ¦å¿µå« min-max æ ååï¼ä¹è¢«ç§°ä¸ºç¦»å·®æ ååï¼æ¯å¯¹åå§æ°æ®ç线æ§åæ¢ï¼ä½¿ç»æå¼æ å°å°[0 - 1]ä¹é´ã 转æ¢å½æ°ä¸ºï¼  è¯·ä½ å°ç¨æ·ä½çé«é¾åº¦è¯å·çå¾å卿¯ä»½è¯å·ä½çè®°å½å æ§è¡ min-max å½ä¸åå缩æ¾å°[0,100]åºé´ï¼å¹¶è¾åºç¨æ· IDãè¯å· IDãå½ä¸åååæ°å¹³åå¼ï¼æåæç §è¯å· ID ååºãå½ä¸ååæ°éåºè¾åºãï¼æ³¨ï¼å¾ååºé´é»è®¤ä¸º[0,100]ï¼å¦ææä¸ªè¯å·ä½çè®°å½ä¸åªæä¸ä¸ªå¾åï¼é£ä¹æ é使ç¨å ¬å¼ï¼å½ä¸å并缩æ¾ååæ°ä»ä¸ºååæ°ï¼ã ç±ç¤ºä¾æ°æ®ç»æè¾åºå¦ä¸ï¼ | uid | exam_id | avg_new_score | | ---- | ------- | ------------- | | 1001 | 9001 | 98 | | 1003 | 9001 | 0 | | 1002 | 9002 | 88 | | 1003 | 9002 | 75 | | 1001 | 9002 | 70 | | 1004 | 9002 | 0 | è§£éï¼é«é¾åº¦è¯å·æ 9001ã9002ã9003ï¼ ä½çäº 9001 çè®°å½æ 3 æ¡ï¼åæ°åå«ä¸º 68ã89ã90ï¼æç»å®å ¬å¼å½ä¸åååæ°ä¸ºï¼0ã95ã100ï¼èå两个å¾å齿¯ç¨æ· 1001 ä½ççï¼å æ¤ç¨æ· 1001 对è¯å· 9001 çæ°å¾å为(95+100)/2â98ï¼åªä¿çæ´æ°é¨åï¼ï¼ç¨æ· 1003 对äºè¯å· 9001 çæ°å¾å为 0ãæåç»ææç §è¯å· ID ååºãå½ä¸ååæ°éåºè¾åºã **æè·¯ï¼** 注æç¹ï¼ 1. å°é«é¾åº¦çè¯å·ï¼ææ¯ç±»è¯å·çå¾åï¼å©ç¨ max/min (col) over()çªå£å½æ°æ±å¾åç»å æå¤§æå°å¼ï¼ç¶åè¿è¡å½ä¸åå ¬å¼è®¡ç®ï¼ç¼©æ¾åºé´ä¸º[0,100]ï¼å³ min_max\*100 2. è¥æç±»è¯å·åªæä¸ä¸ªå¾åï¼åæ é使ç¨å½ä¸åå ¬å¼ï¼å åªæä¸ä¸ªå max_score=min_score,scoreï¼å ¬å¼åç»æå¯è½ä¼åæ 0ã 3. æåç»ææ uidãexam_id åç»æ±å½ä¸åååå¼ï¼score 为 NULL çè¦è¿æ»¤æã æåå°±æ¯ä»ç»çä¸é¢å ¬å¼ ï¼è¯´å®è¯ï¼è¿é¢çèµ·æ¥å°±å¾ç»ï¼ **çæ¡**ï¼ ```sql SELECT uid, exam_id, round(sum(min_max) / count(score), 0) AS avg_new_score FROM ( SELECT *, IF ( max_score = min_score, score, (score - min_score) / (max_score - min_score) * 100 ) AS min_max FROM ( SELECT uid, a.exam_id, score, max(score) over (PARTITION BY a.exam_id) AS max_score, min(score) over (PARTITION BY a.exam_id) AS min_score FROM exam_record a LEFT JOIN examination_info b USING (exam_id) WHERE difficulty = 'hard' ) t WHERE score IS NOT NULL ) t1 GROUP BY uid, exam_id ORDER BY exam_id ASC, avg_new_score DESC; ``` ### æ¯ä»½è¯å·æ¯æä½çæ°åæªæ¢å½æçä½çæ»æ° **æè¿°:** ç°æè¯å·ä½çè®°å½è¡¨ exam_recordï¼uid ç¨æ· ID, exam_id è¯å· ID, start_time å¼å§ä½çæ¶é´, submit_time äº¤å·æ¶é´, score å¾åï¼ï¼ | id | uid | exam_id | start_time | submit_time | score | | ---- | ---- | ------- | ------------------- | ------------------- | ------ | | 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 90 | | 2 | 1002 | 9001 | 2020-01-20 10:01:01 | 2020-01-20 10:10:01 | 89 | | 3 | 1002 | 9001 | 2020-02-01 12:11:01 | 2020-02-01 12:31:01 | 83 | | 4 | 1003 | 9001 | 2020-03-01 19:01:01 | 2020-03-01 19:30:01 | 75 | | 5 | 1004 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:11:01 | 60 | | 6 | 1003 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:41:01 | 90 | | 7 | 1002 | 9001 | 2020-05-02 19:01:01 | 2020-05-02 19:32:00 | 90 | | 8 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:59:01 | 69 | | 9 | 1004 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 | | 10 | 1003 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:31:01 | 68 | | 11 | 1001 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:43:01 | 81 | | 12 | 1001 | 9002 | 2020-03-02 12:11:01 | (NULL) | (NULL) | 请è¾åºæ¯ä»½è¯å·æ¯æä½çæ°åæªæ¢å½æçä½çæ»æ°ã ç±ç¤ºä¾æ°æ®ç»æè¾åºå¦ä¸ï¼ | exam_id | start_month | month_cnt | cum_exam_cnt | | ------- | ----------- | --------- | ------------ | | 9001 | 202001 | 2 | 2 | | 9001 | 202002 | 1 | 3 | | 9001 | 202003 | 3 | 6 | | 9001 | 202005 | 1 | 7 | | 9002 | 202001 | 1 | 1 | | 9002 | 202002 | 3 | 4 | | 9002 | 202003 | 1 | 5 | è§£éï¼è¯å· 9001 å¨ 202001ã202002ã202003ã202005 å ± 4 个ææè¢«ä½çè®°å½ï¼æ¯ä¸ªæè¢«ä½çæ°åå«ä¸º 2ã1ã3ã1ï¼æªæ¢å½æç´¯ç§¯ä½çæ»æ°ä¸º 2ã3ã6ã7ã **æè·¯ï¼** è¿é¢å°±ä¸¤ä¸ªå ³é®ç¹ï¼ç»è®¡æªæ¢å½æçä½çæ»æ°ãè¾åºæ¯ä»½è¯å·æ¯æä½çæ°åæªæ¢å½æçä½çæ»æ° è¿ä¸ªæ¯å ³é®`**sum(count(*)) over(partition by exam_id order by date_format(start_time,'%Y%m'))**` **çæ¡**ï¼ ```sql SELECT exam_id, date_format(start_time, '%Y%m') AS start_month, count(*) AS month_cnt, sum(count(*)) OVER (PARTITION BY exam_id ORDER BY date_format(start_time, '%Y%m')) AS cum_exam_cnt FROM exam_record GROUP BY exam_id, start_month ``` ### æ¯æåæªæ¢å½æçç颿 åµï¼è¾é¾ï¼ **æè¿°**ï¼ç°æè¯å·ä½çè®°å½è¡¨ `exam_record`ï¼`uid` ç¨æ· ID, `exam_id` è¯å· ID, `start_time` å¼å§ä½çæ¶é´, `submit_time` äº¤å·æ¶é´, `score` å¾åï¼ï¼ | id | uid | exam_id | start_time | submit_time | score | | ---- | ---- | ------- | ------------------- | ------------------- | ------ | | 1 | 1001 | 9001 | 2020-01-01 09:01:01 | 2020-01-01 09:21:59 | 90 | | 2 | 1002 | 9001 | 2020-01-20 10:01:01 | 2020-01-20 10:10:01 | 89 | | 3 | 1002 | 9001 | 2020-02-01 12:11:01 | 2020-02-01 12:31:01 | 83 | | 4 | 1003 | 9001 | 2020-03-01 19:01:01 | 2020-03-01 19:30:01 | 75 | | 5 | 1004 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:11:01 | 60 | | 6 | 1003 | 9001 | 2020-03-01 12:01:01 | 2020-03-01 12:41:01 | 90 | | 7 | 1002 | 9001 | 2020-05-02 19:01:01 | 2020-05-02 19:32:00 | 90 | | 8 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-01-02 19:59:01 | 69 | | 9 | 1004 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:20:01 | 99 | | 10 | 1003 | 9002 | 2020-02-02 12:01:01 | 2020-02-02 12:31:01 | 68 | | 11 | 1001 | 9002 | 2020-01-02 19:01:01 | 2020-02-02 12:43:01 | 81 | | 12 | 1001 | 9002 | 2020-03-02 12:11:01 | (NULL) | (NULL) | 请è¾åºèªä»æç¨æ·ä½çè®°å½ä»¥æ¥ï¼æ¯æçè¯å·ä½çè®°å½ä¸ææ´»ç¨æ·æ°ãæ°å¢ç¨æ·æ°ãæªæ¢å½æç忿大æ°å¢ç¨æ·æ°ãæªæ¢å½æçç´¯ç§¯ç¨æ·æ°ãç»æææä»½ååºè¾åºã ç±ç¤ºä¾æ°æ®ç»æè¾åºå¦ä¸ï¼ | start_month | mau | month_add_uv | max_month_add_uv | cum_sum_uv | | ----------- | ---- | ------------ | ---------------- | ---------- | | 202001 | 2 | 2 | 2 | 2 | | 202002 | 4 | 2 | 2 | 4 | | 202003 | 3 | 0 | 2 | 4 | | 202005 | 1 | 0 | 2 | 4 | | month | 1001 | 1002 | 1003 | 1004 | | ------ | ---- | ---- | ---- | ---- | | 202001 | 1 | 1 | | | | 202002 | 1 | 1 | 1 | 1 | | 202003 | 1 | | 1 | 1 | | 202005 | | 1 | | | ç±ä¸è¿°ç©éµå¯ä»¥çåºï¼2020 å¹´ 1 ææ 2 ä¸ªç¨æ·æ´»è·ï¼mau=2ï¼ï¼å½ææ°å¢ç¨æ·æ°ä¸º 2ï¼ 2020 å¹´ 2 ææ 4 ä¸ªç¨æ·æ´»è·ï¼å½ææ°å¢ç¨æ·æ°ä¸º 2ï¼æå¤§åææ°å¢ç¨æ·æ°ä¸º 2ï¼å½åç´¯ç§¯ç¨æ·æ°ä¸º 4ã **æè·¯ï¼** é¾ç¹ï¼ 1.å¦ä½æ±æ¯ææ°å¢ç¨æ· 2.æªè³å½æçç颿 åµ å¤§è´æµç¨ï¼ ï¼1ï¼ç»è®¡æ¯ä¸ªäººç馿¬¡ç»éæä»½ `min()` ï¼2ï¼ç»è®¡æ¯æçææ´»åæ°å¢ç¨æ·æ°ï¼å å¾å°æ¯ä¸ªäººç馿¬¡ç»éæä»½ï¼å坹馿¬¡ç»éæä»½åç»æ±åæ¯è¯¥æä»½çæ°å¢äººæ° ï¼3ï¼ç»è®¡æªæ¢å½æç忿大æ°å¢ç¨æ·æ°ãæªæ¢å½æçç´¯ç§¯ç¨æ·æ° ï¼æç»æç §ææä»½ååºè¾åº **çæ¡**ï¼ ```sql -- æªæ¢å½æç忿大æ°å¢ç¨æ·æ°ãæªæ¢å½æçç´¯ç§¯ç¨æ·æ°ï¼ææä»½ååºè¾åº SELECT start_month, mau, month_add_uv, max( month_add_uv ) over ( ORDER BY start_month ), sum( month_add_uv ) over ( ORDER BY start_month ) FROM ( -- ç»è®¡æ¯æçææ´»åæ°å¢ç¨æ·æ° SELECT date_format( a.start_time, '%Y%m' ) AS start_month, count( DISTINCT a.uid ) AS mau, count( DISTINCT b.uid ) AS month_add_uv FROM exam_record a LEFT JOIN ( -- ç»è®¡æ¯ä¸ªäººç馿¬¡ç»éæä»½ SELECT uid, min( date_format( start_time, '%Y%m' )) AS first_month FROM exam_record GROUP BY uid ) b ON date_format( a.start_time, '%Y%m' ) = b.first_month GROUP BY start_month ) main ORDER BY start_month ```