SQL:WITH AS(CTE)引起的思考
在初学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 中 |
| 表别名在子查询外 | ✗ 不行 | 超出了作用域 |