数据库 (Database)
create database databasename;
功能: 创建新数据库。
语法:
sql
CREATE DATABASE database_name;
示例:
sql
CREATE DATABASE my_shop;
use databasename
功能: 选择要操作的数据库。
语法:
sql
USE database_name;
示例:
sql
USE my_shop;
drop database databasename
功能: 删除数据库及其所有数据(谨慎使用!)。
语法:
sql
DROP DATABASE database_name;
示例:
sql
DROP DATABASE old_backup;
表 (Table)
create
功能: 创建新表。
语法:
sql
CREATE TABLE table_name (
column1 datatype [constraints],
column2 datatype [constraints],
...
);
常用约束: PRIMARY KEY, NOT NULL, UNIQUE, DEFAULT value, FOREIGN KEY
示例:
sql
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
delete from
功能: 从表中删除记录。
语法:
sql
DELETE FROM table_name
WHERE condition;
注意: 如果不加 WHERE 子句,将删除表中所有数据!
示例:
sql
DELETE FROM users
WHERE id = 5;
select
功能: 从表中查询数据(基础形式)。
语法:
sql
SELECT column1, column2, ...
FROM table_name;
示例:
sql
SELECT username, email
FROM users;
insert into
功能: 向表中插入新记录。
语法:
sql
-- 指定列名插入
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);
-- 为所有列插入(需按表结构顺序)
INSERT INTO table_name
VALUES (value1, value2, ...);
示例:
sql
INSERT INTO users (username, email)
VALUES ('john_doe', 'john@example.com');
update tablename
功能: 更新表中已有的记录。
语法:
sql
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
注意: 务必使用 WHERE 子句限定要更新的行,否则会更新所有行!
示例:
sql
UPDATE users
SET email = 'new_email@example.com'
WHERE username = 'john_doe';
SELECT 查询详解
功能: 从数据库表中检索数据,是 SQL 中最核心和复杂的命令。
完整语法结构:
sql
SELECT [DISTINCT] column1, column2, ...
FROM table1
[JOIN table2 ON join_condition]
[WHERE condition]
[GROUP BY column1, column2, ...]
[HAVING group_condition]
[ORDER BY column1 [ASC|DESC], ...]
[LIMIT number]
[OFFSET number];
子句说明与示例:
-
DISTINCT
去除结果中的重复行。
sqlSELECT DISTINCT department FROM employees; -
JOIN
连接多个表。
sql-- 内连接 (INNER JOIN) SELECT orders.id, customers.name FROM orders INNER JOIN customers ON orders.customer_id = customers.id; -- 左连接 (LEFT JOIN) SELECT employees.name, departments.dept_name FROM employees LEFT JOIN departments ON employees.dept_id = departments.id; -
WHERE
过滤行。
sqlSELECT * FROM products WHERE price > 100 AND stock > 0; -
GROUP BY
按列分组,常与聚合函数 (
COUNT,SUM,AVG,MAX,MIN) 一起使用。sqlSELECT department, COUNT(*) as employee_count, AVG(salary) as avg_salary FROM employees GROUP BY department; -
HAVING
过滤分组后的结果(
WHERE用于分组前过滤行)。sqlSELECT department, COUNT(*) as emp_count FROM employees GROUP BY department HAVING COUNT(*) > 5; -
ORDER BY
对结果排序。
sqlSELECT name, score FROM students ORDER BY score DESC; -
LIMIT & OFFSET
限制返回行数和实现分页。
sql-- 获取前10条 SELECT * FROM posts ORDER BY created_at DESC LIMIT 10; -- 获取第11-20条(每页10条的第2页) SELECT * FROM posts ORDER BY created_at DESC LIMIT 10 OFFSET 10;
select
窗口函数
功能: 窗口函数(Window Function)允许在不减少行数的情况下,对一组相关的行(称为"窗口")进行计算,为每一行返回一个值。它与 GROUP BY 聚合不同,不会将多行合并为一行。
基本语法:
sql
SELECT
column1,
column2,
window_function(column3) OVER (
[PARTITION BY partition_column1, partition_column2, ...]
[ORDER BY order_column1 [ASC|DESC], ...]
[frame_clause]
) AS alias_name
FROM table_name;
核心子句说明:
frame_clause: 定义窗口框架,即函数计算时具体考虑分区内的哪些行。常用ROWS BETWEEN ... AND ...或RANGE BETWEEN ... AND ...。
-
语法 :
{ROWS | RANGE} BETWEEN frame_start AND frame_end -
frame_start和frame_end可选值 : -
UNBOUNDED PRECEDING: 分区第一行。 -
n PRECEDING: 当前行之前的第 n 行(ROWS)或值小于当前值 n 个单位内的行(RANGE)。 -
CURRENT ROW: 当前行。 -
n FOLLOWING: 当前行之后的第 n 行(ROWS)或值大于当前值 n 个单位内的行(RANGE)。 -
UNBOUNDED FOLLOWING: 分区最后一行。 -
常用简写 :
-
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW(默认框架,可省略):从分区开始到当前行。 -
ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING:前后各两行,共五行(当前行及前后各两行)。 -
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING:从当前行到分区结束。 -
ROWSvsRANGE: -
ROWS: 按物理行偏移。 -
RANGE: 按逻辑值范围偏移(需配合ORDER BY,且排序列通常为数值或日期类型)。常用窗口函数类别与示例:
1. 排名函数
ROW_NUMBER(): 为分区内的每一行分配一个唯一的连续序号。RANK(): 排名,相同值排名相同,但会留下"空位"。DENSE_RANK(): 密集排名,相同值排名相同,且不留"空位"。
sql
-- 按部门分区,按薪水降序排名
SELECT
name,
department,
salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS row_num,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rank,
DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dense_rank
FROM employees;
2. 聚合函数作为窗口函数
SUM(),AVG(),COUNT(),MIN(),MAX()
sql
-- 计算每个员工的薪水在其部门内的占比
SELECT
name,
department,
salary,
SUM(salary) OVER (PARTITION BY department) AS dept_total_salary,
salary * 100.0 / SUM(salary) OVER (PARTITION BY department) AS salary_percentage
FROM employees;
3. 取值函数
LAG(column, offset): 获取分区内当前行之前第offset行的值。LEAD(column, offset): 获取分区内当前行之后第offset行的值。FIRST_VALUE(column): 获取分区内第一行的值。LAST_VALUE(column): 获取分区内最后一行的值(通常需要指定正确的窗口框架)。
sql
-- 查看每位员工相对于上一位员工的薪水变化
SELECT
name,
department,
salary,
LAG(salary, 1) OVER (PARTITION BY department ORDER BY hire_date) AS prev_salary,
salary - LAG(salary, 1) OVER (PARTITION BY department ORDER BY hire_date) AS salary_change
FROM employees;
4. 分布函数
PERCENT_RANK(): 计算行的相对排名(百分比)。CUME_DIST(): 计算行的累积分布。
窗口框架示例:
sql
-- 计算截至当前行的累计薪水(默认框架:RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
SELECT
name,
hire_date,
salary,
SUM(salary) OVER (ORDER BY hire_date) AS running_total
FROM employees;
-- 计算移动平均(最近3行,包括当前行和前2行)
SELECT
date,
revenue,
AVG(revenue) OVER (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg_3day
FROM daily_sales;
注意事项:
- 窗口函数在
SELECT子句和ORDER BY子句中可用,但不能在WHERE、GROUP BY或HAVING子句中使用。 - 性能:在大数据集上,复杂的窗口函数可能影响查询性能,需合理使用索引和分区。
count
功能: 统计行数或非空值的数量。
语法:
sql
-- 统计所有行数(包括 NULL 值)
SELECT COUNT(*) FROM table_name;
-- 统计指定列中非 NULL 值的数量
SELECT COUNT(column_name) FROM table_name;
-- 结合 DISTINCT 统计唯一值的数量
SELECT COUNT(DISTINCT column_name) FROM table_name;
示例:
sql
-- 统计员工总数
SELECT COUNT(*) AS total_employees FROM employees;
-- 统计有邮箱地址的员工数量
SELECT COUNT(email) AS employees_with_email FROM employees;
-- 统计不重复的部门数量
SELECT COUNT(DISTINCT department) AS unique_departments FROM employees;
case when then else end
功能: 实现条件逻辑,根据条件返回不同的值。
语法:
sql
SELECT
column1,
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
...
ELSE default_result
END AS new_column_name
FROM table_name;
示例:
sql
-- 根据分数划分等级
SELECT
student_name,
score,
CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
WHEN score >= 70 THEN 'C'
WHEN score >= 60 THEN 'D'
ELSE 'F'
END AS grade
FROM exam_results;
-- 简化版 CASE 表达式(等值判断)
SELECT
product_name,
CASE category_id
WHEN 1 THEN 'Electronics'
WHEN 2 THEN 'Clothing'
WHEN 3 THEN 'Books'
ELSE 'Other'
END AS category_name
FROM products;
if NULLIF
功能: IF 函数用于条件判断,NULLIF 函数用于比较两个表达式,相等时返回 NULL。
语法:
sql
-- IF 函数(MySQL)
SELECT IF(condition, value_if_true, value_if_false) FROM table_name;
-- NULLIF 函数(标准 SQL)
SELECT NULLIF(expression1, expression2) FROM table_name;
示例:
sql
-- IF 示例:判断员工是否高薪
SELECT
name,
salary,
IF(salary > 100000, 'High', 'Normal') AS salary_level
FROM employees;
-- NULLIF 示例:避免除零错误
SELECT
total_sales,
number_of_customers,
total_sales / NULLIF(number_of_customers, 0) AS avg_sales_per_customer
FROM sales_summary;
-- 组合使用:如果邮箱为空,显示 'No Email'
SELECT
name,
IF(NULLIF(email, '') IS NULL, 'No Email', email) AS contact_email
FROM users;
子查询
功能: 嵌套在主查询内部的查询,可用于 SELECT、FROM、WHERE、HAVING 等子句中。
语法:
sql
-- 在 WHERE 子句中
SELECT * FROM table1 WHERE column1 IN (SELECT column2 FROM table2);
-- 在 FROM 子句中(派生表)
SELECT * FROM (SELECT * FROM table1) AS subquery_table;
-- 在 SELECT 子句中(标量子查询)
SELECT column1, (SELECT MAX(column2) FROM table2) AS max_value FROM table1;
示例:
sql
-- 找出薪水高于部门平均薪水的员工
SELECT name, department, salary
FROM employees e1
WHERE salary > (
SELECT AVG(salary)
FROM employees e2
WHERE e2.department = e1.department
);
-- 使用派生表计算每个部门的员工数
SELECT department, employee_count
FROM (
SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department
) AS dept_stats;
-- 标量子查询:获取每个产品的类别名称
SELECT
p.product_name,
(SELECT category_name FROM categories c WHERE c.id = p.category_id) AS category
FROM products p;
like
功能: 用于在 WHERE 子句中进行模式匹配(模糊查询)。
语法:
sql
SELECT * FROM table_name WHERE column_name LIKE 'pattern';
通配符说明:
%:匹配任意多个字符(包括零个字符)_:匹配单个字符[charlist]:匹配字符列表中的任意单个字符(部分数据库支持)[^charlist]或[!charlist]:匹配不在字符列表中的任意单个字符
示例:
sql
-- 查找以 'A' 开头的名字
SELECT * FROM employees WHERE name LIKE 'A%';
-- 查找以 'son' 结尾的姓氏
SELECT * FROM employees WHERE last_name LIKE '%son';
-- 查找包含 'admin' 的职位
SELECT * FROM employees WHERE job_title LIKE '%admin%';
-- 查找第二个字符是 'a' 的名字
SELECT * FROM employees WHERE name LIKE '_a%';
-- 查找以 A、B 或 C 开头的名字(MySQL)
SELECT * FROM employees WHERE name REGEXP '^[A-C]';
-- 查找不以数字开头的产品代码
SELECT * FROM products WHERE product_code NOT LIKE '[0-9]%';
join
功能: 用于基于相关列合并两个或多个表中的行。
语法:
sql
SELECT columns
FROM table1
[JOIN_TYPE] JOIN table2 ON table1.column = table2.column;
常用 JOIN 类型:
- INNER JOIN:返回两个表中匹配的行
- LEFT (OUTER) JOIN:返回左表所有行,右表匹配的行,无匹配则为 NULL
- RIGHT (OUTER) JOIN:返回右表所有行,左表匹配的行,无匹配则为 NULL
- FULL (OUTER) JOIN:返回两个表中所有行,匹配的合并,无匹配则为 NULL
- CROSS JOIN :返回两个表的笛卡尔积(所有可能的组合)
示例:
sql
-- INNER JOIN:获取有订单的客户信息
SELECT customers.name, orders.order_date, orders.amount
FROM customers
INNER JOIN orders ON customers.id = orders.customer_id;
-- LEFT JOIN:获取所有客户及其订单(包括没有订单的客户)
SELECT customers.name, orders.order_date, orders.amount
FROM customers
LEFT JOIN orders ON customers.id = orders.customer_id;
-- RIGHT JOIN:获取所有订单及其客户信息(包括没有客户信息的订单)
SELECT customers.name, orders.order_date, orders.amount
FROM customers
RIGHT JOIN orders ON customers.id = orders.customer_id;
-- FULL OUTER JOIN:获取所有客户和所有订单(MySQL 不支持,可用 UNION 模拟)
SELECT customers.name, orders.order_date, orders.amount
FROM customers
LEFT JOIN orders ON customers.id = orders.customer_id
UNION
SELECT customers.name, orders.order_date, orders.amount
FROM customers
RIGHT JOIN orders ON customers.id = orders.customer_id
WHERE customers.id IS NULL;
-- CROSS JOIN:生成所有可能的组合
SELECT colors.color_name, sizes.size_name
FROM colors
CROSS JOIN sizes;
with tablename AS() 临时表
功能: 公共表表达式(CTE),创建临时命名结果集,可在同一查询中多次引用,提高复杂查询的可读性。
语法:
sql
WITH cte_name (column1, column2, ...) AS (
-- 子查询定义
SELECT ...
FROM ...
WHERE ...
)
SELECT * FROM cte_name;
示例:
sql
-- 简单 CTE:计算部门平均薪水
WITH dept_avg AS (
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
)
SELECT e.name, e.department, e.salary, d.avg_salary
FROM employees e
JOIN dept_avg d ON e.department = d.department
WHERE e.salary > d.avg_salary;
-- 递归 CTE:生成数字序列(1 到 10)
WITH RECURSIVE numbers AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1 FROM numbers WHERE n < 10
)
SELECT * FROM numbers;
-- 多个 CTE
WITH
high_salary_employees AS (
SELECT * FROM employees WHERE salary > 100000
),
department_summary AS (
SELECT department, COUNT(*) AS emp_count
FROM high_salary_employees
GROUP BY department
)
SELECT * FROM department_summary ORDER BY emp_count DESC;
distinct
功能: 去除查询结果中的重复行,返回唯一值。
语法:
sql
-- 去除所有列的重复组合
SELECT DISTINCT column1, column2, ... FROM table_name;
-- 结合聚合函数使用
SELECT COUNT(DISTINCT column_name) FROM table_name;
示例:
sql
-- 获取所有不重复的部门名称
SELECT DISTINCT department FROM employees;
-- 获取不重复的(城市,国家)组合
SELECT DISTINCT city, country FROM locations;
-- 统计不重复的客户数量
SELECT COUNT(DISTINCT customer_id) AS unique_customers FROM orders;
-- 注意:DISTINCT 作用于所有选择的列
SELECT DISTINCT first_name, last_name FROM employees;
-- 这可能会返回多行,因为不同的人可能有相同的名字但不同的姓氏