SQL知识点

数据库 (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];

子句说明与示例:

  1. DISTINCT

    去除结果中的重复行。

    sql 复制代码
    SELECT DISTINCT department FROM employees;
  2. 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;
  3. WHERE

    过滤行。

    sql 复制代码
    SELECT * FROM products WHERE price > 100 AND stock > 0;
  4. GROUP BY

    按列分组,常与聚合函数 (COUNT, SUM, AVG, MAX, MIN) 一起使用。

    sql 复制代码
    SELECT department, COUNT(*) as employee_count, AVG(salary) as avg_salary
    FROM employees
    GROUP BY department;
  5. HAVING

    过滤分组后的结果(WHERE 用于分组前过滤行)。

    sql 复制代码
    SELECT department, COUNT(*) as emp_count
    FROM employees
    GROUP BY department
    HAVING COUNT(*) > 5;
  6. ORDER BY

    对结果排序。

    sql 复制代码
    SELECT name, score FROM students ORDER BY score DESC;
  7. 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;

核心子句说明:

  1. frame_clause : 定义窗口框架,即函数计算时具体考虑分区内的哪些行。常用 ROWS BETWEEN ... AND ...RANGE BETWEEN ... AND ...
  • 语法{ROWS | RANGE} BETWEEN frame_start AND frame_end

  • frame_startframe_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:从当前行到分区结束。

  • ROWS vs RANGE

  • 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 子句中可用,但不能在 WHEREGROUP BYHAVING 子句中使用。
  • 性能:在大数据集上,复杂的窗口函数可能影响查询性能,需合理使用索引和分区。

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;

子查询

功能: 嵌套在主查询内部的查询,可用于 SELECTFROMWHEREHAVING 等子句中。

语法:

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;
-- 这可能会返回多行,因为不同的人可能有相同的名字但不同的姓氏
相关推荐
Database_Cool_1 小时前
记忆张量MemOS + 阿里云PolarDB一站式记忆管理方案发布:给AI装上不断片的记忆
数据库·人工智能·阿里云
码农阿豪1 小时前
上线前能跑,上线后挂了,三个隐性的SQL陷阱
数据库·sql
春卷同学1 小时前
032-关系型数据库在记账应用中的建模与查询优化
java·jvm·数据库
foolishlee1 小时前
openGauss慢SQL记录相关线程
数据库
数行拙笔2 小时前
Redis---list类型
数据库·redis·缓存
人工智能培训3 小时前
世界模型内嵌,感知交互跃迁
大数据·数据库·人工智能·神经网络·生成对抗网络
隔壁阿布都3 小时前
ClickHouse完整指南
服务器·数据库·clickhouse
TDengine (老段)3 小时前
TDengine JOIN 完整语法 — Inner/Outer/ASOF/Window 全语法详解
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
ai_coder_ai3 小时前
编写自动化脚本,在自己后端服务中使用云原生Baas服务进行编码和解码相关操作
数据库·云原生·自动化