表、行、列:SQL 到底在操作什么
先把表格模型想清楚:表是数据集合,行是对象,列是对象的属性。
SQL Basics
短文章 + 小例子 + 对应练习,先把查询语言的基本动作练稳。
先把表格模型想清楚:表是数据集合,行是对象,列是对象的属性。
SELECT 决定要哪些列,FROM 决定从哪张表取,这是所有查询的起点。
WHERE 用来筛选行,先从等于、大于、IN、AND/OR 这些条件开始。
ORDER BY、LIMIT、DISTINCT 是做列表题最常用的三个工具。
NULL 表示未知或缺失,判断和统计时都要单独处理。
聚合的核心是“按什么分组”和“每组算什么”。
JOIN 的重点不是语法,而是找对两张表之间的关联键。
Article Index
每篇都围绕一个真实分析任务,先说明思路,再指向对应练习。
把注册月、活跃月和留存口径拆开,避免把自然月和 30 天窗口混在一起。
用 FILTER 和去重用户数计算转化率,适合活动复盘和产品路径诊断。
用日期范围替代函数包裹列,让查询保持 sargable,给索引发挥空间。
理解 PARTITION BY 和 ORDER BY 的分工,写出每组 Top N、上一笔、累计值。
Query Patterns
先套结构,再替换表名、字段和条件,降低从问题到 SQL 的启动成本。
适合“找最高/最新/最活跃”的列表型问题。
SELECT name, metric
FROM table_name
WHERE condition
ORDER BY metric DESC
LIMIT 10;适合统计“每个客户/每个城市/每个商品”,包括没有行为的对象。
SELECT d.name, coalesce(sum(f.amount), 0) AS total
FROM dim d
LEFT JOIN fact f ON f.dim_id = d.id
GROUP BY d.name;适合每个用户最大订单、每个城市最新记录、每个类别 Top 商品。
SELECT *
FROM (
SELECT t.*, row_number() OVER (PARTITION BY group_key ORDER BY metric DESC) AS rn
FROM table_name t
) ranked
WHERE rn = 1;避免 EXTRACT 包裹时间列,保留索引扫描机会。
SELECT id
FROM orders
WHERE created_at >= '2026-02-01'
AND created_at < '2026-03-01';Concept Ledger
把易混点压成短说明,帮助你回到练习场继续写。
WHERE 过滤行,发生在 GROUP BY 前;HAVING 过滤组,发生在聚合后。
count(*) 数行,count(列) 不数 NULL;LEFT JOIN 统计时尤其重要。
WITH 给中间结果命名,适合先聚合、再过滤、再 JOIN 的多步问题。
先区分 Seq Scan 和 Index Scan,再看过滤条件、JOIN 方式和估算行数。