SQL 语法速查 · 以 Hive SQL 为例演示
SELECT column1, column2 FROM table_name;
SELECT * FROM employees;
SELECT DISTINCT department FROM employees;
SELECT name AS employee_name, salary AS monthly_salary FROM employees AS e;
| id | name | department | salary |
|---|---|---|---|
| 1 | 张三 | 技术部 | 15000 |
| 2 | 李四 | 技术部 | 18000 |
| 3 | 王五 | 市场部 | 12000 |
SELECT name, salary FROM employees;
查询结果
| name | salary |
|---|---|
| 张三 | 15000 |
| 李四 | 18000 |
| 王五 | 12000 |
SELECT * FROM employees WHERE salary > 15000;
WHERE salary > 10000 AND department = '技术部';
WHERE department IN ('技术部', '市场部');
WHERE salary BETWEEN 10000 AND 20000;
WHERE name LIKE '张%'; -- 匹配以'张'开头的名字
SELECT * FROM employees ORDER BY salary DESC;
SELECT * FROM employees ORDER BY salary DESC LIMIT 10;
WHERE manager_id IS NULL; WHERE email IS NOT NULL;
| 函数 | 说明 | 示例 |
|---|---|---|
| COUNT(*) | 计算行数 | COUNT(*) → 3 |
| SUM(col) | 求和 | SUM(salary) → 45000 |
| AVG(col) | 平均值 | AVG(salary) → 15000 |
| MAX(col) | 最大值 | MAX(salary) → 18000 |
| MIN(col) | 最小值 | MIN(salary) → 12000 |
SELECT department, AVG(salary) AS avg_salary FROM employees GROUP BY department;
SELECT department, COUNT(*) AS cnt FROM employees GROUP BY department HAVING COUNT(*) > 2;
原始数据 (employees)
| dept | salary |
|---|---|
| 技术部 | 15000 |
| 技术部 | 18000 |
| 市场部 | 12000 |
| 市场部 | 10000 |
查询结果
| dept | avg_salary |
|---|---|
| 技术部 | 16500 |
| 市场部 | 11000 |
原始数据 (employees)
| dept | name |
|---|---|
| 技术部 | 张三 |
| 技术部 | 李四 |
| 技术部 | 王五 |
| 市场部 | 赵六 |
| 市场部 | 孙七 |
查询结果 (HAVING COUNT(*) > 2)
| dept | cnt |
|---|---|
| 技术部 | 3 |
💡 市场部只有2人,被 HAVING 过滤掉了
| 类型 | 说明 | 保留数据 |
|---|---|---|
| INNER JOIN | 内连接 | 仅匹配的行 |
| LEFT JOIN | 左连接 | 左表全部 + 匹配的右表 |
| RIGHT JOIN | 右连接 | 右表全部 + 匹配的左表 |
| FULL JOIN | 全连接 | 两表全部 |
employees 表
| id | name | dept_id |
|---|---|---|
| 1 | 张三 | 10 |
| 2 | 李四 | 20 |
| 3 | 王五 | NULL |
departments 表
| id | dept_name |
|---|---|
| 10 | 技术部 |
| 20 | 市场部 |
SELECT e.name, d.dept_name FROM employees e LEFT JOIN departments d ON e.dept_id = d.id;
查询结果
| name | dept_name |
|---|---|
| 张三 | 技术部 |
| 李四 | 市场部 |
| 王五 | NULL |
-- 窗口函数基本语法 函数名() OVER( PARTITION BY 分组列 -- 可选:按什么分组 ORDER BY 排序列 -- 可选:组内如何排序 ROWS BETWEEN ... AND ... -- 可选:窗口范围 )
| 函数 | 说明 | 示例结果 |
|---|---|---|
| ROW_NUMBER() | 行号(连续不重复) | 1, 2, 3, 4 |
| RANK() | 排名(并列后跳跃) | 1, 1, 3, 4 |
| DENSE_RANK() | 排名(并列后连续) | 1, 1, 2, 3 |
| LAG(col, n) | 向前取第n行的值 | 取上一行数据 |
| LEAD(col, n) | 向后取第n行的值 | 取下一行数据 |
| SUM() OVER() | 累计求和 | 100, 250, 450 |
原始数据 (employees)
| name | dept | salary |
|---|---|---|
| 张三 | 技术部 | 15000 |
| 李四 | 技术部 | 18000 |
| 王五 | 市场部 | 12000 |
SELECT name, dept, salary, ROW_NUMBER() OVER(PARTITION BY dept ORDER BY salary DESC) AS rn, SUM(salary) OVER(PARTITION BY dept) AS dept_total FROM employees;
查询结果
| name | dept | salary | rn | dept_total |
|---|---|---|---|---|
| 李四 | 技术部 | 18000 | 1 | 33000 |
| 张三 | 技术部 | 15000 | 2 | 33000 |
| 王五 | 市场部 | 12000 | 1 | 12000 |
SELECT name, CASE WHEN salary >= 20000 THEN '高薪' WHEN salary >= 10000 THEN '中薪' ELSE '低薪' END AS salary_level FROM employees;
SELECT name FROM table1 UNION ALL SELECT name FROM table2;
WITH high_salary AS ( SELECT * FROM employees WHERE salary > 15000 ) SELECT * FROM high_salary;
SELECT * FROM employees WHERE salary > ( SELECT AVG(salary) FROM employees );
| 函数 | 说明 | 示例 |
|---|---|---|
| DATEDIFF(expr1, expr2) | 返回 expr1 - expr2 的天数 | → 9 |
| DATE_ADD(date, INTERVAL n DAY) | 日期加 n 天 | → '2024-01-08' |
| DATE_SUB(date, INTERVAL n DAY) | 日期减 n 天 | → '2024-01-07' |
| DATEDIFF(end, start) | 返回 end - start 的天数 | → 9 |
| DATE_ADD(date, n) | 日期加 n 天 (整数) | → '2024-01-08' |
| DATE_SUB(date, n) | 日期减 n 天 (整数) | → '2024-01-07' |
| dateDiff('day', start, end) | 计算日期差 | → 9 |
| addDays(date, n) | 日期加 n 天 | → '2024-01-08' |
| subtractDays(date, n) | 日期减 n 天 | → '2024-01-07' |
| DATE_FORMAT(date, fmt) | 格式化日期 | → '2024-01' |
| 函数 | 说明 | 示例 |
|---|---|---|
| CONCAT(s1, s2) | 拼接字符串 | → 'HelloWorld' |
| SUBSTR(s, pos, len) | 截取子串 | → 'Hel' |
| LENGTH(s) | 返回字符串长度(Bytes) | → 5 |
| lengthUTF8(s) | 返回字符串字符数 | → 5 |
| length(s) | 返回字符串字节数 | → 5 |
| TRIM(s) | 去除首尾空格 | → 'Hi' |