这篇文章不会有详细的教程,你需要跟大模型一起成长

目标

环境准备

安装VSCode + DuckDB,就可以在本地用SQL操作csv文件了

https://marketplace.visualstudio.com/items?itemName=RandomFractalsInc.duckdb-sql-tools

user_id,username,phone
1,张三,13800138001
2,李四,13900139002
3,王五,13700137003
order_id,user_id,amount,status
1001,1,250.00,已支付
1002,1,88.50,待付款
1003,2,1200.00,已发货

用DuckDB导入这两个文件就可以查询了

SQL基础语法

SELECT username, phone
FROM users
WHERE username = '张三'
SELECT * FROM orders ORDER BY amount DESC;

因为用户信息和订单信息在不同的文件/表里,你需要把它们“拼”起来, 比如下面通过user_id拼起来

SELECT orders.order_id, users.username, orders.amount
FROM orders
LEFT JOIN users ON orders.user_id = users.user_id;

求和

SELECT SUM(amount) FROM orders;

分组统计

SELECT user_id, SUM(amount) 
FROM orders 
GROUP BY user_id;

COUNT(): 统计行数(例如:总共有多少个订单)。

SUM(): 求和(例如:本月总销售额)。

AVG(): 平均值(例如:客单价)。

MAX() / MIN(): 最大/最小值(例如:最高的一笔消费)

你可以把它想象成“套娃”:先通过内层的查询算出一个结果,再把这个结果交给外层的查询去使用。

SELECT * FROM users 
WHERE user_id IN (SELECT DISTINCT user_id FROM orders);

简单来说,CTE 就是把一个复杂的子查询“拎出来”定义成一个临时结果集,并给它起个名字。它就像是 SQL 脚本里的临时变量,让你的代码读起来像是在讲故事,而不是在玩套娃。而且可以复用,不用重复写多次

这里我们没用子查询,而是定义了一个临时表order_summary,就不用在select语句写复杂的代码了

WITH order_summary AS (
    SELECT DISTINCT user_id 
    FROM orders
)
SELECT u.* FROM users u
LEFT JOIN order_summary s ON u.user_id = s.user_id;
操作符含义比喻
UNION并集A + B (去重)
INTERSECT交集A 和 B 共同有的部分
EXCEPT差集A 有但 B 没有的部分

找出那些注册了但从来没买过东西的用户

SELECT user_id FROM users
EXCEPT
SELECT user_id FROM orders;

练习题