在初学SQL阶段,做到了一道sql的题目:

描述

题目:现在运营想要查看用户在某天刷题后第二天还会再来刷题的留存率。请你取出相应数据。

示例:question_practice_detail

id device_id question_id result date
1 2138 111 wrong 2021-05-03
2 3214 112 wrong 2021-05-09
3 3214 113 wrong 2021-06-15
4 6543 111 right 2021-08-13
5 2315 115 right 2021-08-13
6 2315 116 right 2021-08-14
7 2315 117 wrong 2021-08-15
8 3214 112 wrong 2021-05-09
9 3214 113 wrong 2021-08-15
10 6543 111 right 2021-08-13
11 2315 115 right 2021-08-13
12 2315 116 right 2021-08-14
13 2315 117 wrong 2021-08-15
14 3214 112 wrong 2021-08-16
15 3214 113 wrong 2021-08-18
16 6543 111 right 2021-08-13

根据示例,你的查询应返回以下结果:

avg_ret
0.3000

我在看了题解之后想要使用WITH AS创建一个虚拟表方便后续的使用:

但是

`with date1 as (

select distinct device_id,date

from question_practice_detail

)

select count(*)/count(date1.device_id) as avg_ret

from (

select distinct d1.device_id,d1.date

from date1 d1

join date1 d2

on d1.device_id = d2.device_id AND d1.date = DATE_ADD(d2.date,interval 1 day)

) as date2`

以上这段代码会出错,但是把count(date1.device_id)换成(SELECT COUNT(*) FROM date1)就是正确的?涉及到的语法问题我想搞清楚。

于是问了AI,他给了我一个规则:

SQL 标准的别名访问规则

| 场景 | 能否访问? | 原因 |

|——————-|——-|—————–|

| CTE 在 FROM 中 | ✓ 可以 | FROM 直接包含它 |

| CTE 在子查询中 | ✓ 可以 | 子查询形成新作用域,可向上访问 |

| CTE 在聚合函数参数中 | ✗ 不行 | 不是一个完整的查询上下文 |

| 表别名 d1 在同层 SELECT | ✓ 可以 | d1 在当前 FROM 中 |

| 表别名在子查询外 | ✗ 不行 | 超出了作用域 |