当前位置: 首页 > news >正文

数据库定义和操作语句的重要语法

数据库📊的10种语法

数据查询语句

  • select : 用于从数据库中检索数据。
select column1, column2,....
from table_name
where condition;
  • select distinct : 用于从数据库中检索唯一的数据值。
select DISTINCT column1, clumn2,...
from table_name;

工作原理如下:

  • 数据库系统会遍历指定列的所有值。
  • 系统会将遇到的每个不同的值添加到结果集中。
  • 最终,结果集中将包含列中的所有唯一值。

这种方法适用于任何列,但对于大型数据集可能会产生一些性能开销,因为数据库需要遍历整个列来找到唯一值。

  • order by : 用于对查询结果进行排序。用在select的末尾。
select column1,column2, ...
from table_name
order by column1 [ASC|DESC], column2 [ASC|DESC],...;

数据插入、更新和删除语句

  • insert into : 用于将新数据插入到数据库表中。
insert into table_name (column1, column2, column3...)
values (value1, value2, value3,...);
  • update : 用于更新数据库表中的现有数据。
update table_name
set column1=value1, column2=value2,...
where condition;
  • delete from : 用于从数据库表中删除数据。
delete from table_name
where condition;

数据库结构定义和修改语句

  • create table : 用于创建数据库表。
create table_name(column1 datetype,column2 datatype,...
);
  • alter table : 用于修改数据库表的结构。
alter table table_name
add column_name datatype;alter table table_name
modify column_name datatype;alter table table_name
drop column_name;
  • drop table : 用于删除数据库表。
drop table table_name;
  • 创建索引:用于加速查询数据库中的数据,使得系统能够快速定位,范围查询和加速排序和连接目标值。

CREAT INDEX idx_department_id ON employees (department_id);-- 查询所有部门为101的员工
SELECT * FROM employees where department_id = 101;

在这个查询中,如果 department_id 列上有索引,数据库系统可能会选择使用该索引来加速查询。

数据库连接查询语句

  1. JOIN : 用于连接两个或多个表的行,根据指定的条件关联行。
    • inner join : 返回两个表中满足条件的行。
    • outer join : 返回两个表中至少有一行满足条件的行。 

更复杂的语法:高级查询和数据处理

这些语法用于处理更复杂的查询需求,例如多表联合查询汇总统计条件过滤等。

子查询

1. 嵌套查询: 在一个查询中嵌套另一个查询,用于检索嵌套查询的结果。

select column1
from table1
where column2 in (select columns from table2 where condition);

2. EXIST: 检查子查询是否返回结果,通常与WHERE子句一起使用,

select column1
from table1
where exists(select * from table2 where condition);

3. IN: 指定一系列条件,如果某列的值在这个系列中,则返回结果。

select column1
from table1
where column2 in (value1, value2,...);

连接查询

1. inner join: 返回两个表中满足条件的行。
select column1, column2
from table1
inner join table2 on table1.column = table2.column;

其中,select column1, column2: 这部分指定了你希望从结果中集中显示的列。在这个例子中,你选择了表'table1'中的'colum1'和'column2'。

from table1: 指定主要表的部分,既要从中选择数据的表。在这里,主要表是‘table1’。

inner join table2 on table1.column = table2.column : 这里是连接表的部分。通过使用inner join,你正在执行内连接,这意味着只有在两个表中的指定列的值相匹配的情况下,相关的行才会包含在结果集中。

  • 'table2':这是要与主要表'table1'进行连接的第二个表。
  • 'on table1.column = table2.column': 这是指定连接条件的部分。他告诉数据库在哪两个表的列上进行匹配。在这里,它表示只有在'table1'的列与'table2'的列相等时,两个表的行才会连接。

该查询目的:这个查询的目的是从‘table1’和‘table2’中选择'table1'的'column1'和'column2',并且只选择那些在连接条件中匹配的行。

举例:假设你有两个表,employees包含员工的信息,包括ID(employee_id),姓名(employee_name),和所属部门的ID(departmet_id)。departments包含部门的信息,包括部门ID(department_id)和部门名称(department_name)。

现想要获取每个员工及其所属部门的名称

# SQL
select employees.employee_id, employees.employee_name, departments.department_name
from employees
inner join departments on employees.department_id = departments.department_id;

这个查询的含义是:

  • employees 表中选择员工的ID (employee_id) 和姓名 (employee_name)。
  • departments 表中选择部门的名称 (department_name)。
  • 通过内连接 (INNER JOIN) 将这两个表连接起来,连接条件是 employees.department_id = departments.department_id,即员工所属部门的ID要与部门表中的ID相匹配。

内连接的好处

  1. 关联数据:内连接使你能够关联两个表中相关的数据,通过共享相同值的列将他们连接起来,不必手动整合。
  2. 减少数据冗余:内连接仅返回满足条件的行,从而减少了结果集中的数据冗余。避免了不相关数据的混入。
  3. 提高查询灵活性:内连接允许你在查询中指定多个表,并且可以通过不同的连接条件创建不同的关联。
  4. 优化性能:仅返回满足条件的行,查询可更快,不需要处理不想干数据。

内连接的强大体现在在关系型数据库中从多个表中检索和组合数据,提供了更丰富和有关联的查询结果。

从四个表中连接表后,查询结果的例子:

select t1.column1, t2.column2, t3.column3, t4.column4
from table t1
inner join table2 t2 on t1.common_colum = t2.common_column
inner join table3 t3 on t2.another_common_column = t3.another_common_column
inner join table4 t4 on t3.yet_another_common_column = t4.yet_another_common_column;
  • t1, t2, t3, t4是表的别名,简化了查询语句。
  • 'common_column', 'another_common_column', 'yet_another_common_column'是连接表的列,用于建立连接关系。
2. 外连接Outer join:允许检索表中未匹配的行,并在结果集中以NULL返回这些行。

外连接分为左外连接(left outer join)、右外连接(right outer join)和全外连接(full outer join)。

1. 左外连接例子

举例:假设你有两个表,employees包含员工的信息,包括ID(employee_id),姓名(employee_name),和所属部门的ID(departmet_id)。departments包含部门的信息,包括部门ID(department_id)和部门名称(department_name)。

employees表

| employee_id | employee_name | department_id |
|-------------|---------------|---------------|
| 1           | John          | 101           |
| 2           | Jane          | 102           |
| 3           | Bob           | 103           |

departments表:

| department_id | department_name |
|---------------|------------------|
| 101           | HR             |
| 102           | IT             |
| 104           | Marketing      |

现打算获取所有员工及其所属部门的名称,包括那些没有匹配到部门的员工。你可以使用左外连接来实现。

select employees.employee_id, employees.employee_name, departments.department_name
from employees
left outer join departments on employees.department_id = departments.departments_id

语句含义:最终会返回employees 表中的所有行,不论它们在 departments 表中是否有匹配的部门信息。如果某个员工没有匹配到部门,departments 表的相关列将会包含 NULL 值。

left outer join结果:

| employee_id | employee_name | department_name |
|-------------|---------------|------------------|
| 1           | John          | HR               |
| 2           | Jane          | IT               |
| 3           | Bob           | NULL             |
2. 右外连接right outer join例子:

右外连接,以返回departments表中所有数据为基准,employees中缺失值补NULL:

SELECT employees.employee_id, employees.employee_name, departments.department_name
FROM employees
RIGHT OUTER JOIN departments ON employees.department_id = departments.department_id;

在这个查询中,RIGHT OUTER JOIN 表示右外连接。这意味着将返回 departments 表中的所有行,不论它们在 employees 表中是否有匹配的员工信息。如果某个部门没有匹配到员工,employees 表的相关列将会包含 NULL 值。

结果如下:

| employee_id | employee_name | department_name |
|-------------|---------------|------------------|
| 1           | John          | HR               |
| 2           | Jane          | IT               |
| NULL        | NULL          | Marketing        |
3. 全外连接full outer join例子

右外连接,以返回employees表和departments表中所有数据为基准,employees和departments中缺失值补NULL:

SELECT employees.employee_id, employees.employee_name, departments.department_name
FROM employees
FULL OUTER JOIN departments ON employees.department_id = departments.department_id;

运行结果:

| employee_id | employee_name | department_name |
|-------------|---------------|------------------|
| 1           | John          | HR               |
| 2           | Jane          | IT               |
| 3           | Bob           | NULL             |
| NULL        | NULL          | Marketing        |

这个结果集包含了 employeesdepartments 表中的所有记录,不论它们在另一个表中是否有匹配。如果某个记录在其中一个表中没有匹配,相应的列将包含 NULL 值。

连接查询进阶

1. UNION:合并两个或多个SELECT语句的结果集,并去除重复的行。

SELECT column1 FROM table1
UNION
SELECT column1 FROM table2;

2. INTERSECT: 返回两个SELECT语句的交集,并去除重复的行。

SELECT column1 FROM table1
INTERSECT
SELECT column1 FROM table2;

3. EXCEPT(或MINUS):

返回第一个 SELECT 语句的结果集,去除与第二个 SELECT 语句的结果集相交的部分。

SELECT column1 FROM table1
EXCEPT
SELECT column1 FROM table2;

窗口函数

1. OVER:用于在执行聚合函数时,定义窗口,使得聚合函数可以对指定窗口的行进行计算。

SELECT column1, AVG(column2) OVER (PARTITION BY column3 ORDER BY column4) As avg_column2
FROM table;

示例数据

+---------+---------+---------+---------+
| column1 | column2 | column3 | column4 |
+---------+---------+---------+---------+
|   A     |    10   |    X    |    3    |
|   B     |    15   |    X    |    1    |
|   C     |    20   |    X    |    2    |
|   D     |    8    |    Y    |    1    |
|   E     |    12   |    Y    |    3    |
|   F     |    18   |    Y    |    2    |
+---------+---------+---------+---------+


1. 对于分区 X,按照 column4 的顺序排序后的数据是:

+---------+---------+---------+---------+
| column1 | column2 | column3 | column4 |
+---------+---------+---------+---------+
|   B     |    15   |    X    |    1    |
|   C     |    20   |    X    |    2    |
|   A     |    10   |    X    |    3    |
+---------+---------+---------+---------+

计算 AVG(column2) 时,按照 column4 的升序顺序计算:

  • 对于第一行(B),平均值是15(自身)。
  • 对于第二行(C),平均值是 (15 + 20) / 2 = 17.5。
  • 对于第三行(A),平均值是 (15 + 20 + 10) / 3 = 15。

2. 对于分区 Y,按照 column4 的顺序排序后的数据是:

+---------+---------+---------+---------+
| column1 | column2 | column3 | column4 |
+---------+---------+---------+---------+
|   D     |    8    |    Y    |    1    |
|   F     |    18   |    Y    |    2    |
|   E     |    12   |    Y    |    3    |
+---------+---------+---------+---------+

计算 AVG(column2) 时,按照 column4 的升序顺序计算:

  • 对于第一行(D),平均值是8(自身)。
  • 对于第二行(F),平均值是 (8 + 18) / 2 = 13。
  • 对于第三行(E),平均值是 (8 + 18 + 12) / 3 = 15。

最终结果:

+---------+------------+
| column1 | avg_column2|
+---------+------------+
|   B     |     15     |  -- 在分区X中,第一行的平均值是15
|   C     |     17.5   |  -- 在分区X中,前两行的平均值是 (15 + 20) / 2 = 17.5
|   A     |     15     |  -- 在分区X中,前三行的平均值是 (15 + 20 + 10) / 3 = 15
|   D     |     8      |  -- 在分区Y中,第一行的平均值是8
|   F     |     13     |  -- 在分区Y中,前两行的平均值是 (8 + 18) / 2 = 13
|   E     |     15     |  -- 在分区Y中,前三行的平均值是 (8 + 18 + 12) / 3 = 15
+---------+------------+

解释

在 SQL 中,`AVG()` 是一个聚合函数,它计算指定列的平均值。当你在窗口函数中使用 `AVG()` 时,它通常是以当前行及其之前的行为基础进行计算的,具体取决于 `OVER` 子句中的 `ORDER BY` 子句和 `PARTITION BY` 子句。

在你的查询中:

SELECT column1, AVG(column2) OVER (PARTITION BY column3 ORDER BY column4) AS avg_column2
FROM table;

- PARTITION BY column3: 指定了窗口函数将按照 `column3` 的不同值进行分区,每个分区内的计算是独立的。
- ORDER BY column4:指定了窗口函数计算平均值时要按照 `column4` 列的值进行排序,以确定计算的顺序和范围。

具体来说,对于每个分区,`AVG(column2)` 将按照 `column4` 列的顺序计算当前行及其之前的行的平均值。这不是规定每行的平均值是前几行的平均值,而是根据 `column4` 的排序顺序计算当前行及其之前的行的平均值。

因此,虽然在通常的情况下,`AVG()` 确实是从第一行到当前行的平均值,但具体计算的范围还受到 `ORDER BY` 子句的影响,确切的计算方式还取决于你的数据和排序列的值。希望这次的解释更加清楚。

全文搜索

1. MATCH AGAINST: 用于在全文搜索中匹配文本。

SELECT column1
FROM table1
WHERE MATCH(column2) AGAINST ('search_keyword');

含义:语句表示在表table1的column2列中执行全文搜索,寻找包含指定搜索关键字的匹配相,并返回对应的column1列的数据。

具体来说:

  • SELECT column1: 查询结果将包括 column1 列的数据,即返回与搜索条件匹配的相关信息。

  • FROM table1: 数据将从名为 table1 的表中检索。

  • WHERE MATCH(column2) AGAINST ('search_keyword'): 这是实际的搜索条件。它要求在 column2 列中执行全文搜索,寻找包含给定搜索关键字('search_keyword')的匹配项。匹配度高的结果将排在前面。

需要注意的是,为了使用这种全文搜索,表中的 column2 列通常需要进行全文索引的配置。此外,MySQL 的全文搜索还涉及到一些配置参数和算法,以满足特定的搜索需求。

存储过程和触发器

它们是在数据库中用于执行特定任务的两种对象。它们通常与关系型数据库系统(如MySQL、SQL Server、Oracle等)一起使用。

1. CREATE PROCEDURE: 用于创建存储过程。

  • 定义: 存储过程是一组预编译的SQL语句,可以被存储在数据库中,并通过一个单独的调用来执行。
  • 创建过程: 创建存储过程通常涉及使用数据库管理系统提供的特定语法,其中包括过程的名称、输入参数、输出参数和过程体(包含SQL语句的代码块)。
  • 用途: 存储过程可以用于封装、重用和简化数据库操作。它们可以被调用,以执行一系列的SQL语句,并且还能接收参数,使其更加灵活。
CREATE PROCEDURE sp_GetCustomerInfo(IN customerID INT)
BEGINSELECT * FROM Customers WHERE CustomerID = customerID;
END;

2. CREATE TRIGGER: 用于创建触发器。

  • 定义:触发器是与表相关联的一种特殊类型的存储过程,它会在表上的特定时间(如插入、更新、删除)发生时自动执行。
  • 创建过程:创建触发器需要指定触发的时间、触发的表、触发时机(BEFORE或AFTER)以及触发时执行的SQL语句。
  • 用途:触发器常用语实现数据的完整性、自动化任务、日志记录等。它们可以用来强制执行特定的业务规则,以确保数据库中的数据始终保持一致性。
CREATE TRIGGER trigger_name
BEFORE/AFTER INSERT/UPDATE/DELETE ON table_name
FOR EACH ROW
-- trigger body

示例

CREATE TRIGGER before_insert_example
BEFORE INSERT ON Orders
FOR EACH ROW
BEGINSET NEW.OrderDate() = NOW();
END;

这是一个MySQL语法下的触发器创建语句,它的作用是在往Orders表中插入新记录之前(BEFORE INSERT)执行一些特定的操作。让我们逐步解释这个触发器的定义:

  • CREATE TRIGGER before_insert_example: 这部分指定了创建触发器的语法,before_insert_example是触发器的名称,你可以根据需要自定义触发器的名字。

  • BEFORE INSERT ON Orders: 这部分说明了触发器是在Orders表上执行的,而且是在插入操作之前触发。

  • FOR EACH ROW: 这表示这是一个行级触发器,也就是说,它会在每次插入一行记录时执行一次。

  • BEGIN...END: 这是触发器的主体,包含了触发器要执行的代码块。在这个例子中,使用了SET NEW.OrderDate = NOW();,它的作用是将即将插入的新记录的OrderDate字段设置为当前的系统时间(使用NOW()函数)。

总体而言,这个触发器的目的是在每次往Orders表插入新记录之前,自动将该记录的OrderDate字段设置为当前时间。这可以用于确保在插入新订单时,OrderDate字段总是包含当前的时间戳,而不是由插入语句提供的值。触发器提供了一种在数据库中自动执行特定逻辑的方式,以确保数据的一致性和完整性。

聚合函数

聚合函数是用于对一组值进行计算并返回单个结果的SQL函数。这些函数通常用于对数据库中的数据进行汇总和统计,提供了对数据集合进行分析的强大工具。

1. SUM:计算某列的总和。

select SUM(column1) from table1;

2. AVG: 计算某列的平均值。

select AVG(column1) from table1;

3. COUNT: 计算某列的行数。

select COUNT(column1) from table1;

4. MAX: 获取某列的最大值。

select max(column1) from table1;

5. MIN: 获取某列的最小值。

select min(column1) from table1;

GROUP BY 和 HAVING

1. GROUP BY: 对查询结果按例进行分组:
select column1, COUNT(*)
from table1
group by column1;

解释

  • select column1, count(*): 选择查询结果中的列,其中包括column1列和一个计算每个分组中行的数量的计数值。count(*)表示对每个分组中的行数进行计数。
  • from table: 指定查询的数据来源,即要统计的表是table。
  • group by column1: 根据column1列的值对结果进行分组。这意味着查询将返回每个不同的column1值以及该值出现的次数。

举例1

| column1 |
|---------|
| A       |
| B       |
| A       |
| A       |
| B       |
| C       |

运行上述查询后,结果可能是:

| column1 | COUNT(*) |
|---------|----------|
| A       | 3        |
| B       | 2        |
| C       | 1        |

解释结果

  • "A" 出现了 3 次。
  • "B" 出现了 2 次。
  • "C" 出现了 1 次。

这种查询对于了解数据分布查找出现频率最高的项等情况非常有用。

举例2:

table1包含以下数据:

| column1 | column2 |
|---------|---------|
| A       | X       |
| B       | Y       |
| A       | X       |
| A       | Z       |
| B       | Z       |
| C       | Y       |

运行以下查询:

SELECT column1, column2, COUNT(*)
FROM table1
GROUP BY column1, column2;

可能的结果是:

| column1 | column2 | COUNT(*) |
|---------|---------|----------|
| A       | X       | 2        |
| B       | Y       | 1        |
| A       | Z       | 1        |
| B       | Z       | 1        |
| C       | Y       | 1        |

这表示按照 column1column2 的组合进行分组,然后计算每个组合的行数。例如,"A" 和 "X" 的组合出现了 2 次,"B" 和 "Y" 的组合出现了 1 次,以此类推。

2. HAVING: 在GROUP BY的基础上进行条件过滤。
select column1, COUNT(*)
from table1
group by coumn1
having count(*) > 1;

解释:

这是一个带有having子句的sql查询语句,用于从表table1中选择出现次数大于1的不同column1值以及它们的出现次数。

  • select column1, count(*): 选择查询结果中的列,包括column1列和一个计算每个分组中行的数量的计数值。count(*)表示对每个分组中的行数进行计数。
  • from table1: 指定查询的数据来源,即要统计的表是table1。
  • group by column1: 根据 column1 列的值对结果进行分组。这意味着查询将返回每个不同的 column1 值以及该值出现的次数。
  • HAVING COUNT(*) > 1: 通过 HAVING 子句筛选出现次数大于 1 的分组。这样,结果将只包含那些在 column1 列中出现次数大于 1 的值。

举例:

table1如下:

| column1 |
|---------|
| A       |
| B       |
| A       |
| A       |
| B       |
| C       |

运行上面查询语句的结果可能是:

| column1 | COUNT(*) |
|---------|----------|
| A       | 3        |
| B       | 2        |

这表示在 column1 列中,只有 "A" 和 "B" 出现的次数大于 1。这种查询常用于查找具有重复出现的特定值的情况。

3. group by 和聚合函数sum的组合使用

假如有table1:

| column1 | column2 | some_numeric_column |
|---------|---------|---------------------|
| A       | X       | 10                  |
| B       | Y       | 5                   |
| A       | X       | 7                   |
| A       | Z       | 3                   |
| B       | Z       | 8                   |
| C       | Y       | 12                  |

运行:

SELECT column1, column2, SUM(some_numeric_column)
FROM table1
GROUP BY column1, column2;

可能的结果:

| column1 | column2 | SUM(some_numeric_column) |
|---------|---------|---------------------------|
| A       | X       | 17                        |
| B       | Y       | 5                         |
| A       | Z       | 3                         |
| B       | Z       | 8                         |
| C       | Y       | 12                        |

这表示按照 column1column2 的组合进行分组,并计算每个组合中 some_numeric_column 列的总和。

相关文章:

  • 分布式系统架构设计之分布式缓存技术选型
  • Java实战项目三:图书借阅系统
  • 新版Edge卸载
  • spring Security源码讲解-WebSecurityConfigurerAdapter
  • HarmonyOS4.0系统性深入开发14AbilityStage组件容器
  • gookit/color - Go语言命令行色彩使用库教程
  • sql:定时执行存储过程(嵌套存储过程、使用游标)
  • 算法训练营第三十天|332.重新安排行程 51. N皇后 37. 解数独
  • 202402读书笔记|《当你老了》——灰蒙曙光比爱情温柔,清晨露珠比希望更可爱
  • 如何实现服务器主动向客户端推送实时数据
  • CSS尺寸单位详解(rpx、px、pt、em、rem、%、vh、vw的区别)
  • pod 基础 2
  • 惠普83752A合成扫频器/信号源0.01-20GHz
  • imgaug库指南(四):从入门到精通的【图像增强】之旅
  • flutter学习-day22-使用GestureDetector识别手势事件
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • [译] 怎样写一个基础的编译器
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • markdown编辑器简评
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • 警报:线上事故之CountDownLatch的威力
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 聊聊redis的数据结构的应用
  • 使用docker-compose进行多节点部署
  • 我从编程教室毕业
  • 我看到的前端
  • 小程序button引导用户授权
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • 带你开发类似Pokemon Go的AR游戏
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #{}和${}的区别是什么 -- java面试
  • #NOIP 2014#Day.2 T3 解方程
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (python)数据结构---字典
  • (八)c52学习之旅-中断实验
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (论文阅读30/100)Convolutional Pose Machines
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (转)一些感悟
  • (转载)利用webkit抓取动态网页和链接
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET Remoting学习笔记(三)信道
  • .net 开发怎么实现前后端分离_前后端分离:分离式开发和一体式发布
  • .NET 药厂业务系统 CPU爆高分析
  • .Net(C#)常用转换byte转uint32、byte转float等
  • .NET开发人员必知的八个网站
  • .NET面试题(二)
  • .NET运行机制
  • @RequestBody的使用
  • [ C++ ] STL---string类的使用指南