SQL 快速指南



SQL - 概述

SQL 是一种操作数据库的语言;它包括数据库创建、删除、获取行、修改行等。SQL 是 **ANSI**(美国国家标准学会)标准语言,但 SQL 语言有很多不同的版本。

什么是 SQL?

SQL 是结构化查询语言,它是一种用于存储、操作和检索存储在关系数据库中的数据的计算机语言。

SQL 是关系数据库系统的标准语言。所有关系数据库管理系统 (RDMS),例如 MySQL、MS Access、Oracle、Sybase、Informix、Postgres 和 SQL Server 都使用 SQL 作为其标准数据库语言。

此外,它们还使用不同的方言,例如:

  • MS SQL Server 使用 T-SQL,
  • Oracle 使用 PL/SQL,
  • MS Access 的 SQL 版本称为 JET SQL(本机格式)等。

为什么要使用 SQL?

SQL 非常流行,因为它提供了以下优势:

  • 允许用户访问关系数据库管理系统中的数据。

  • 允许用户描述数据。

  • 允许用户定义数据库中的数据并操作该数据。

  • 允许使用 SQL 模块、库和预编译器嵌入到其他语言中。

  • 允许用户创建和删除数据库和表。

  • 允许用户在数据库中创建视图、存储过程和函数。

  • 允许用户设置表、过程和视图的权限。

SQL 简史

  • **1970** 年 - IBM 的 Edgar F. "Ted" Codd 博士被称为关系数据库之父。他描述了数据库的关系模型。

  • **1974** 年 - 结构化查询语言出现。

  • **1978** 年 - IBM 致力于开发 Codd 的想法并发布了一个名为 System/R 的产品。

  • **1986** 年 - IBM 开发了关系数据库的第一个原型,并由 ANSI 标准化。第一个关系数据库由 Relational Software 发布,后来被称为 Oracle。

SQL 过程

当您为任何 RDBMS 执行 SQL 命令时,系统会确定执行您的请求的最佳方法,SQL 引擎会确定如何解释该任务。

此过程中包含各种组件。

这些组件包括:

  • 查询调度程序
  • 优化引擎
  • 经典查询引擎
  • SQL 查询引擎等。

经典查询引擎处理所有非 SQL 查询,但 SQL 查询引擎不会处理逻辑文件。

下图显示了 SQL 架构的简单示意图:

SQL Architecture

SQL 命令

与关系数据库交互的标准 SQL 命令为 CREATE、SELECT、INSERT、UPDATE、DELETE 和 DROP。根据其性质,这些命令可以分为以下几组:

DDL - 数据定义语言

序号 命令和描述
1

CREATE

创建数据库中的新表、表的视图或其他对象。

2

ALTER

修改现有数据库对象,例如表。

3

DROP

删除数据库中的整个表、表的视图或其他对象。

DML - 数据操纵语言

序号 命令和描述
1

SELECT

从一个或多个表中检索某些记录。

2

INSERT

创建记录。

3

UPDATE

修改记录。

4

DELETE

删除记录。

DCL - 数据控制语言

序号 命令和描述
1

GRANT

授予用户权限。

2

REVOKE

收回授予用户的权限。

SQL - RDBMS 概念

什么是 RDBMS?

RDBMS 代表 ****系 ****据 **** ****理 ****统。RDBMS 是 SQL 和所有现代数据库系统(如 MS SQL Server、IBM DB2、Oracle、MySQL 和 Microsoft Access)的基础。

关系数据库管理系统 (RDBMS) 是一种基于 E. F. Codd 引入的关系模型的数据库管理系统 (DBMS)。

什么是表?

RDBMS 中的数据存储在称为 **表** 的数据库对象中。该表基本上是相关数据条目的集合,它包含许多列和行。

请记住,表是关系数据库中最常见和最简单的存储数据形式。以下程序是 CUSTOMERS 表的示例:

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

什么是字段?

每个表都细分为称为字段的较小实体。CUSTOMERS 表中的字段包括 ID、NAME、AGE、ADDRESS 和 SALARY。

字段是表中的一列,旨在维护有关表中每个记录的特定信息。

什么是记录或行?

记录也称为数据行,是表中存在的每个单独条目。例如,上面的 CUSTOMERS 表中有 7 条记录。以下是 CUSTOMERS 表中的一行数据或记录:

+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
+----+----------+-----+-----------+----------+

记录是表中的水平实体。

什么是列?

列是表中的垂直实体,包含与表中特定字段关联的所有信息。

例如,CUSTOMERS 表中的一列是 ADDRESS,它表示位置描述,如下所示:

+-----------+
| ADDRESS   |
+-----------+
| Ahmedabad |
| Delhi     |
| Kota      |
| Mumbai    |
| Bhopal    |
| MP        |
| Indore    |
+----+------+

什么是 NULL 值?

表中的 NULL 值是字段中看起来为空白的值,这意味着具有 NULL 值的字段是没有任何值的字段。

理解 NULL 值与零值或包含空格的字段不同非常重要。具有 NULL 值的字段是在创建记录时留空的字段。

SQL 约束

约束是在表上数据列上实施的规则。它们用于限制可以进入表的的数据类型。这确保了数据库中数据的准确性和可靠性。

约束可以是列级或表级。列级约束仅应用于一列,而表级约束应用于整个表。

以下是 SQL 中一些最常用的约束:

  • NOT NULL 约束 - 确保列不能具有 NULL 值。

  • UNIQUE 约束 - 确保列中的所有值都不同。

  • 主键 - 唯一标识数据库表中的每一行/记录。

  • 外键 - 唯一标识任何其他数据库表中的每一行/记录。

  • 索引 - 用于非常快速地创建和检索数据库中的数据。

数据完整性

每个 RDBMS 都存在以下类别的数据完整性:

  • 实体完整性 - 表中没有重复行。

  • 域完整性 - 通过限制值的类型、格式或范围,强制执行给定列的有效条目。

  • 参照完整性 - 不能删除被其他记录引用的行。

  • 用户定义完整性 - 强制执行一些不属于实体、域或参照完整性的特定业务规则。

数据库规范化

数据库规范化是有效组织数据库中数据的过程。此规范化过程有两个原因 -

  • 消除冗余数据,例如,在多个表中存储相同的数据。

  • 确保数据依赖关系合理。

这两个原因都是值得追求的目标,因为它们减少了数据库占用的空间并确保数据以逻辑方式存储。规范化包括一系列指导原则,可帮助您创建良好的数据库结构。

规范化指导原则分为范式;可以将范式视为数据库结构的格式或布局方式。范式的目标是组织数据库结构,使其符合第一范式、第二范式和最终第三范式的规则。

您可以选择进一步进行,进入第四范式、第五范式等,但通常,第三范式已经足够了。

SQL - RDBMS 数据库

有很多流行的 RDBMS 可供使用。本教程简要概述了一些最流行的 RDBMS。这将帮助您比较它们的基本功能。

MySQL

MySQL 是一个开源的 SQL 数据库,由一家瑞典公司 MySQL AB 开发。MySQL 发音为“my ess-que-ell”,与 SQL 的发音“sequel”形成对比。

MySQL 支持许多不同的平台,包括 Microsoft Windows、主要的 Linux 发行版、UNIX 和 Mac OS X。

MySQL 具有免费版和付费版,具体取决于其用途(非商业/商业)和功能。MySQL 带有一个非常快速、多线程、多用户且健壮的 SQL 数据库服务器。

历史

  • Michael Widenius 和 David Axmark 从 1994 年开始开发 MySQL。

  • 1995 年 5 月 23 日首次内部发布。

  • 1998 年 1 月 8 日发布了 Windows 版本,适用于 Windows 95 和 NT。

  • 版本 3.23:2000 年 6 月发布测试版,2001 年 1 月发布正式版。

  • 版本 4.0:2002 年 8 月发布测试版,2003 年 3 月发布正式版(联合体)。

  • 版本 4.1:2004 年 6 月发布测试版,2004 年 10 月发布正式版。

  • 版本 5.0:2005 年 3 月发布测试版,2005 年 10 月发布正式版。

  • 2008 年 2 月 26 日,Sun Microsystems 收购了 MySQL AB。

  • 版本 5.1:2008 年 11 月 27 日发布正式版。

功能

  • 高性能。
  • 高可用性。
  • 可扩展性和灵活性 运行任何内容。
  • 强大的事务支持。
  • Web 和数据仓库优势。
  • 强大的数据保护。
  • 全面的应用程序开发。
  • 易于管理。
  • 开源自由和 24x7 支持。
  • 最低的总拥有成本。

MS SQL Server

MS SQL Server 是由 Microsoft Inc. 开发的关系数据库管理系统。其主要查询语言为 -

  • T-SQL
  • ANSI SQL

历史

  • 1987 年 - Sybase 发布适用于 UNIX 的 SQL Server。

  • 1988 年 - Microsoft、Sybase 和 Aston-Tate 将 SQL Server 移植到 OS/2。

  • 1989 年 - Microsoft、Sybase 和 Aston-Tate 发布适用于 OS/2 的 SQL Server 1.0。

  • 1990 年 - 发布 SQL Server 1.1,支持 Windows 3.0 客户端。

  • Aston-Tate 退出 SQL Server 开发。

  • 2000 年 - Microsoft 发布 SQL Server 2000。

  • 2001 年 - Microsoft 发布适用于 SQL Server Web 版本 1 的 XML(下载)。

  • 2002 年 - Microsoft 发布 SQLXML 2.0(从适用于 SQL Server 的 XML 重命名)。

  • 2002 年 - Microsoft 发布 SQLXML 3.0。

  • 2005 年 - Microsoft 于 2005 年 11 月 7 日发布 SQL Server 2005。

功能

  • 高性能
  • 高可用性
  • 数据库镜像
  • 数据库快照
  • CLR 集成
  • 服务代理
  • DDL 触发器
  • 排名函数
  • 基于行版本的隔离级别
  • XML 集成
  • TRY...CATCH
  • 数据库邮件

ORACLE

它是一个非常大型的多用户数据库管理系统。Oracle 是由 Oracle Corporation 开发的关系数据库管理系统。

Oracle 致力于有效地管理其资源,即网络中多个请求和发送数据的客户端之间的信息数据库。

它是客户端/服务器计算的绝佳数据库服务器选择。Oracle 支持客户端和服务器的所有主要操作系统,包括 MSDOS、NetWare、UnixWare、OS/2 和大多数 UNIX 版本。

历史

Oracle 成立于 1977 年,在业界庆祝其 32 周年(从 1977 年到 2009 年)。

  • 1977 年 - Larry Ellison、Bob Miner 和 Ed Oates 成立了软件开发实验室以开展开发工作。

  • 1979 年 - 发布了 Oracle 2.0 版本,它成为第一个商业关系数据库和第一个 SQL 数据库。公司更名为 Relational Software Inc. (RSI)。

  • 1981 年 - RSI 开始为 Oracle 开发工具。

  • 1982 年 - RSI 更名为 Oracle Corporation。

  • 1983 年 - Oracle 发布了 3.0 版本,该版本用 C 语言重写并在多个平台上运行。

  • 1984 年 - 发布了 Oracle 4.0 版本。它包含并发控制等功能 - 多版本读一致性等。

  • 1985 年 - 发布了 Oracle 4.0 版本。它包含并发控制等功能 - 多版本读一致性等。

  • 2007 年 - Oracle 发布了 Oracle11g。新版本侧重于更好的分区、轻松迁移等。

功能

  • 并发
  • 读取一致性
  • 锁定机制
  • 使数据库处于静止状态
  • 可移植性
  • 自管理数据库
  • SQL*Plus
  • ASM
  • 调度程序
  • 资源管理器
  • 数据仓库
  • 物化视图
  • 位图索引
  • 表压缩
  • 并行执行
  • 分析 SQL
  • 数据挖掘
  • 分区

MS ACCESS

这是 Microsoft 最受欢迎的产品之一。Microsoft Access 是一款入门级数据库管理软件。MS Access 数据库不仅价格低廉,而且对于小型项目来说也是一个功能强大的数据库。

MS Access 使用 Jet 数据库引擎,该引擎使用特定的 SQL 语言方言(有时称为 Jet SQL)。

MS Access 附带 MS Office 套件的专业版。MS Access 具有易于使用的直观图形界面。

  • 1992 年 - 发布 Access 1.0 版本。

  • 1993 年 - 发布 Access 1.1 版本,以提高与包含 Access Basic 编程语言的兼容性。

  • 最重大的转变是从 Access 97 到 Access 2000。

  • 2007 年 - Access 2007 引入了一种新的数据库格式 ACCDB,它支持复杂的数据类型,例如多值和附件字段。

功能

  • 用户可以创建表、查询、窗体和报表,并使用宏将它们连接在一起。

  • 可以选择将数据导入和导出到许多格式,包括 Excel、Outlook、ASCII、dBase、Paradox、FoxPro、SQL Server、Oracle、ODBC 等。

  • 还有 Jet 数据库格式(Access 2007 中的 MDB 或 ACCDB),它可以将应用程序和数据包含在一个文件中。这使得将整个应用程序分发给其他用户非常方便,他们可以在断开连接的环境中运行它。

  • Microsoft Access 提供参数化查询。这些查询和 Access 表可以从其他程序(如 VB6 和 .NET)通过 DAO 或 ADO 进行引用。

  • Microsoft SQL Server 的桌面版可以用作 Jet 数据库引擎的替代方案。

  • Microsoft Access 是一个基于文件服务器的数据库。与客户端-服务器关系数据库管理系统 (RDBMS) 不同,Microsoft Access 不实现数据库触发器、存储过程或事务日志记录。

SQL - 语法

SQL 后跟一组独特的规则和指南,称为语法。本教程通过列出所有基本 SQL 语法,使您快速入门 SQL。

所有 SQL 语句都以 SELECT、INSERT、UPDATE、DELETE、ALTER、DROP、CREATE、USE、SHOW 等任何关键字开头,并且所有语句都以分号 (;) 结尾。

这里需要注意的最重要的一点是 SQL 不区分大小写,这意味着 SELECT 和 select 在 SQL 语句中具有相同的含义。而 MySQL 会区分表名。因此,如果您使用的是 MySQL,则需要按数据库中存在的名称提供表名。

SQL 中的各种语法

本教程中提供的所有示例均已在 MySQL 服务器上进行了测试。

SQL SELECT 语句

SELECT column1, column2....columnN
FROM   table_name;

SQL DISTINCT 子句

SELECT DISTINCT column1, column2....columnN
FROM   table_name;

SQL WHERE 子句

SELECT column1, column2....columnN
FROM   table_name
WHERE  CONDITION;

SQL AND/OR 子句

SELECT column1, column2....columnN
FROM   table_name
WHERE  CONDITION-1 {AND|OR} CONDITION-2;

SQL IN 子句

SELECT column1, column2....columnN
FROM   table_name
WHERE  column_name IN (val-1, val-2,...val-N);

SQL BETWEEN 子句

SELECT column1, column2....columnN
FROM   table_name
WHERE  column_name BETWEEN val-1 AND val-2;

SQL LIKE 子句

SELECT column1, column2....columnN
FROM   table_name
WHERE  column_name LIKE { PATTERN };

SQL ORDER BY 子句

SELECT column1, column2....columnN
FROM   table_name
WHERE  CONDITION
ORDER BY column_name {ASC|DESC};

SQL GROUP BY 子句

SELECT SUM(column_name)
FROM   table_name
WHERE  CONDITION
GROUP BY column_name;

SQL COUNT 子句

SELECT COUNT(column_name)
FROM   table_name
WHERE  CONDITION;

SQL HAVING 子句

SELECT SUM(column_name)
FROM   table_name
WHERE  CONDITION
GROUP BY column_name
HAVING (arithematic function condition);

SQL CREATE TABLE 语句

CREATE TABLE table_name(
column1 datatype,
column2 datatype,
column3 datatype,
.....
columnN datatype,
PRIMARY KEY( one or more columns )
);

SQL DROP TABLE 语句

DROP TABLE table_name;

SQL CREATE INDEX 语句

CREATE UNIQUE INDEX index_name
ON table_name ( column1, column2,...columnN);

SQL DROP INDEX 语句

ALTER TABLE table_name
DROP INDEX index_name;

SQL DESC 语句

DESC table_name;

SQL TRUNCATE TABLE 语句

TRUNCATE TABLE table_name;

SQL ALTER TABLE 语句

ALTER TABLE table_name {ADD|DROP|MODIFY} column_name {data_ype};

SQL ALTER TABLE 语句(重命名)

ALTER TABLE table_name RENAME TO new_table_name;

SQL INSERT INTO 语句

INSERT INTO table_name( column1, column2....columnN)
VALUES ( value1, value2....valueN);

SQL UPDATE 语句

UPDATE table_name
SET column1 = value1, column2 = value2....columnN=valueN
[ WHERE  CONDITION ];

SQL DELETE 语句

DELETE FROM table_name
WHERE  {CONDITION};

SQL CREATE DATABASE 语句

CREATE DATABASE database_name;

SQL DROP DATABASE 语句

DROP DATABASE database_name;

SQL USE 语句

USE database_name;

SQL COMMIT 语句

COMMIT;

SQL ROLLBACK 语句

ROLLBACK;

SQL - 数据类型

SQL 数据类型是指定任何对象数据类型的属性。每个列、变量和表达式在 SQL 中都有一个相关的数据类型。在创建表时可以使用这些数据类型。您可以根据需要为表列选择数据类型。

SQL Server 提供六类数据类型供您使用,如下所示 -

精确数值数据类型

数据类型
bigint -9,223,372,036,854,775,808 9,223,372,036,854,775,807
int -2,147,483,648 2,147,483,647
smallint -32,768 32,767
tinyint 0 255
bit 0 1
decimal -10^38 +1 10^38 -1
numeric -10^38 +1 10^38 -1
money -922,337,203,685,477.5808 +922,337,203,685,477.5807
smallmoney -214,748.3648 +214,748.3647

近似数值数据类型

数据类型
float -1.79E + 308 1.79E + 308
real -3.40E + 38 3.40E + 38

日期和时间数据类型

数据类型
datetime 1753 年 1 月 1 日 9999 年 12 月 31 日
smalldatetime 1900 年 1 月 1 日 2079 年 6 月 6 日
date 存储日期,例如 1991 年 6 月 30 日
time

存储一天中的时间,例如 12:30 PM。

注意 − 在这里,datetime 的精度为 3.33 毫秒,而 smalldatetime 的精度为 1 分钟。

字符字符串数据类型

序号 数据类型和描述
1

char

最大长度为 8,000 个字符。(固定长度非 Unicode 字符)

2

varchar

最大 8,000 个字符。(可变长度非 Unicode 数据)。

3

varchar(max)

最大长度为 2E + 31 个字符,可变长度非 Unicode 数据(仅限 SQL Server 2005)。

4

text

可变长度非 Unicode 数据,最大长度为 2,147,483,647 个字符。

Unicode 字符串数据类型

序号 数据类型和描述
1

nchar

最大长度为 4,000 个字符。(固定长度 Unicode)

2

nvarchar

最大长度为 4,000 个字符。(可变长度 Unicode)

3

nvarchar(max)

最大长度为 2E + 31 个字符(仅限 SQL Server 2005)。(可变长度 Unicode)

4

ntext

最大长度为 1,073,741,823 个字符。(可变长度 Unicode)

二进制数据类型

序号 数据类型和描述
1

binary

最大长度为 8,000 字节(固定长度二进制数据)

2

varbinary

最大长度为 8,000 字节。(可变长度二进制数据)

3

varbinary(max)

最大长度为 2E + 31 字节(仅限 SQL Server 2005)。(可变长度二进制数据)

4

image

最大长度为 2,147,483,647 字节。(可变长度二进制数据)

其他数据类型

序号 数据类型和描述
1

sql_variant

存储各种 SQL Server 支持的数据类型的值,除了 text、ntext 和 timestamp。

2

timestamp

存储数据库范围内的唯一编号,每当更新一行时都会更新该编号

3

uniqueidentifier

存储全局唯一标识符 (GUID)

4

xml

存储 XML 数据。您可以将 xml 实例存储在列或变量中(仅限 SQL Server 2005)。

5

cursor

对游标对象的引用

6

table

存储结果集以供以后处理

SQL - 运算符

什么是 SQL 中的操作符?

操作符是保留字或字符,主要用于 SQL 语句的 WHERE 子句中执行操作(例如比较和算术运算)。这些操作符用于在 SQL 语句中指定条件,并用作语句中多个条件的连接词。

  • 算术运算符
  • 比较运算符
  • 逻辑运算符
  • 用于否定条件的操作符

SQL 算术运算符

假设“变量 a”持有 10,“变量 b”持有 20,则 -

显示示例

运算符 描述 示例
+(加法) 将运算符两侧的值相加。 a + b 将得到 30
-(减法) 从左操作数中减去右操作数。 a - b 将得到 -10
*(乘法) 将运算符两侧的值相乘。 a * b 将得到 200
/(除法) 将左操作数除以右操作数。 b / a 将得到 2
%(模数) 将左操作数除以右操作数并返回余数。 b % a 将得到 0

SQL 比较运算符

假设“变量 a”持有 10,“变量 b”持有 20,则 -

显示示例

运算符 描述 示例
= 检查两个操作数的值是否相等,如果相等则条件为真。 (a = b)不为真。
!= 检查两个操作数的值是否相等,如果不相等则条件为真。 (a != b)为真。
<> 检查两个操作数的值是否相等,如果不相等则条件为真。 (a <> b)为真。
> 检查左操作数的值是否大于右操作数的值,如果大于则条件为真。 (a > b)不为真。
< 检查左操作数的值是否小于右操作数的值,如果小于则条件为真。 (a < b)为真。
>= 检查左操作数的值是否大于或等于右操作数的值,如果大于或等于则条件为真。 (a >= b)不为真。
<= 检查左操作数的值是否小于或等于右操作数的值,如果小于或等于则条件为真。 (a <= b)为真。
!< 检查左操作数的值是否不小于右操作数的值,如果满足则条件为真。 (a !< b)为假。
!> 检查左操作数的值是否不大于右操作数的值,如果满足则条件为真。 (a !> b)为真。

SQL 逻辑运算符

以下是 SQL 中所有可用逻辑运算符的列表。

显示示例

序号 运算符和描述
1

ALL

ALL 运算符用于将值与另一个值集中所有值进行比较。

2

AND

AND 运算符允许 SQL 语句的 WHERE 子句中存在多个条件。

3

ANY

ANY 运算符用于将值与列表中任何适用的值进行比较,具体取决于条件。

4

BETWEEN

BETWEEN 运算符用于搜索在给定最小值和最大值的一组值内的值。

5

EXISTS

EXISTS 运算符用于搜索指定表中是否存在满足特定条件的行。

6

IN

IN 运算符用于将值与已指定的文字值列表进行比较。

7

LIKE

LIKE 运算符用于使用通配符运算符将值与类似的值进行比较。

8

NOT

NOT 运算符反转与其一起使用的逻辑运算符的含义。例如:NOT EXISTS、NOT BETWEEN、NOT IN 等。这是一个否定运算符。

9

OR

OR 运算符用于组合 SQL 语句的 WHERE 子句中的多个条件。

10

IS NULL

NULL 运算符用于将值与 NULL 值进行比较。

11

UNIQUE

UNIQUE 运算符搜索指定表中的每一行以确保唯一性(无重复)。

SQL - 表达式

表达式是结合了一个或多个值、运算符和 SQL 函数,并计算出一个值。这些 SQL 表达式就像公式一样,它们是用查询语言编写的。您还可以使用它们查询数据库以获取特定数据集。

语法

考虑以下 SELECT 语句的基本语法 -

SELECT column1, column2, columnN 
FROM table_name 
WHERE [CONDITION|EXPRESSION];

有不同类型的 SQL 表达式,如下所述 -

  • 布尔型
  • 数值型
  • 日期型

现在让我们详细讨论一下这些内容。

布尔表达式

SQL 布尔表达式根据匹配单个值来获取数据。以下是语法 -

SELECT column1, column2, columnN 
FROM table_name 
WHERE SINGLE VALUE MATCHING EXPRESSION;

考虑 CUSTOMERS 表具有以下记录 -

SQL> SELECT * FROM CUSTOMERS;
+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+
7 rows in set (0.00 sec)

下表是一个简单的示例,显示了各种 SQL 布尔表达式的用法 -

SQL> SELECT * FROM CUSTOMERS WHERE SALARY = 10000;
+----+-------+-----+---------+----------+
| ID | NAME  | AGE | ADDRESS | SALARY   |
+----+-------+-----+---------+----------+
|  7 | Muffy |  24 | Indore  | 10000.00 |
+----+-------+-----+---------+----------+
1 row in set (0.00 sec)

数值表达式

这些表达式用于在任何查询中执行任何数学运算。以下是语法 -

SELECT numerical_expression as  OPERATION_NAME
[FROM table_name
WHERE CONDITION] ;

这里,numerical_expression 用于数学表达式或任何公式。以下是一个简单的示例,显示了 SQL 数值表达式的用法 -

SQL> SELECT (15 + 6) AS ADDITION
+----------+
| ADDITION |
+----------+
|       21 |
+----------+
1 row in set (0.00 sec)

有几个内置函数,如 avg()、sum()、count() 等,用于执行针对表或特定表列的聚合数据计算。

SQL> SELECT COUNT(*) AS "RECORDS" FROM CUSTOMERS; 
+---------+
| RECORDS |
+---------+
|       7 |
+---------+
1 row in set (0.00 sec)

日期表达式

日期表达式返回当前系统日期和时间值 -

SQL>  SELECT CURRENT_TIMESTAMP;
+---------------------+
| Current_Timestamp   |
+---------------------+
| 2009-11-12 06:40:23 |
+---------------------+
1 row in set (0.00 sec)

另一个日期表达式如下所示 -

SQL>  SELECT  GETDATE();;
+-------------------------+
| GETDATE                 |
+-------------------------+
| 2009-10-22 12:07:18.140 |
+-------------------------+
1 row in set (0.00 sec)

SQL - 创建数据库

SQL 的CREATE DATABASE语句用于创建新的 SQL 数据库。

语法

此 CREATE DATABASE 语句的基本语法如下 -

CREATE DATABASE DatabaseName;

数据库名称始终应该在 RDBMS 中唯一。

示例

如果要创建新的数据库<testDB>,则 CREATE DATABASE 语句将如下所示 -

SQL> CREATE DATABASE testDB;

在创建任何数据库之前,请确保您具有管理员权限。创建数据库后,您可以按照以下步骤在数据库列表中检查它 -

SQL> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| AMROOD             |
| TUTORIALSPOINT     |
| mysql              |
| orig               |
| test               |
| testDB             |
+--------------------+
7 rows in set (0.00 sec)

SQL - 删除或删除数据库

SQL 的DROP DATABASE语句用于删除 SQL 模式中现有的数据库。

语法

DROP DATABASE 语句的基本语法如下 -

DROP DATABASE DatabaseName;

数据库名称始终应该在 RDBMS 中唯一。

示例

如果要删除现有数据库<testDB>,则 DROP DATABASE 语句将如下所示 -

SQL> DROP DATABASE testDB;

注意 - 在使用此操作之前请小心,因为删除现有数据库会导致数据库中存储的完整信息丢失。

在删除任何数据库之前,请确保您具有管理员权限。删除数据库后,您可以按照以下步骤在数据库列表中检查它 -

SQL> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| AMROOD             |
| TUTORIALSPOINT     |
| mysql              |
| orig               |
| test               |
+--------------------+
6 rows in set (0.00 sec)

SQL - 选择数据库,USE 语句

当 SQL 模式中有多个数据库时,在开始操作之前,您需要选择一个数据库来执行所有操作。

SQL 的USE语句用于在 SQL 模式中选择任何现有数据库。

语法

USE 语句的基本语法如下所示 -

USE DatabaseName;

数据库名称始终应该在 RDBMS 中唯一。

示例

您可以检查可用的数据库,如下所示 -

SQL> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| AMROOD             |
| TUTORIALSPOINT     |
| mysql              |
| orig               |
| test               |
+--------------------+
6 rows in set (0.00 sec)

现在,如果要使用 AMROOD 数据库,则可以执行以下 SQL 命令并开始使用 AMROOD 数据库。

SQL> USE AMROOD;

SQL - 创建表

创建基本表涉及命名表并定义其列以及每列的数据类型。

SQL 的CREATE TABLE语句用于创建新表。

语法

CREATE TABLE 语句的基本语法如下 -

CREATE TABLE table_name(
   column1 datatype,
   column2 datatype,
   column3 datatype,
   .....
   columnN datatype,
   PRIMARY KEY( one or more columns )
);

CREATE TABLE 是告诉数据库系统您想要做什么的关键字。在这种情况下,您想要创建一个新表。表的唯一名称或标识符位于 CREATE TABLE 语句之后。

然后在括号中是定义表中每一列以及它是什么类型数据的列表。通过以下示例,语法变得更加清晰。

可以使用 CREATE TABLE 语句和 SELECT 语句的组合来创建现有表的副本。您可以在使用另一个表创建表中查看完整详细信息。

示例

以下代码块是一个示例,它创建了一个 CUSTOMERS 表,其中 ID 作为主键,NOT NULL 是约束条件,表示在创建此表中的记录时,这些字段不能为 NULL -

SQL> CREATE TABLE CUSTOMERS(
   ID   INT              NOT NULL,
   NAME VARCHAR (20)     NOT NULL,
   AGE  INT              NOT NULL,
   ADDRESS  CHAR (25) ,
   SALARY   DECIMAL (18, 2),       
   PRIMARY KEY (ID)
);

您可以通过查看 SQL 服务器显示的消息来验证您的表是否已成功创建,否则您可以使用以下 DESC 命令 -

SQL> DESC CUSTOMERS;
+---------+---------------+------+-----+---------+-------+
| Field   | Type          | Null | Key | Default | Extra |
+---------+---------------+------+-----+---------+-------+
| ID      | int(11)       | NO   | PRI |         |       |
| NAME    | varchar(20)   | NO   |     |         |       |
| AGE     | int(11)       | NO   |     |         |       |
| ADDRESS | char(25)      | YES  |     | NULL    |       |
| SALARY  | decimal(18,2) | YES  |     | NULL    |       |
+---------+---------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

现在,您在数据库中可以使用 CUSTOMERS 表来存储与客户相关的必要信息。

SQL - 删除或删除表

SQL DROP TABLE 语句用于删除表定义以及该表的所有数据、索引、触发器、约束和权限规范。

注意 - 使用此命令时应非常小心,因为一旦删除表,则该表中所有可用信息也将永远丢失。

语法

此 DROP TABLE 语句的基本语法如下 -

DROP TABLE table_name;

示例

让我们首先验证 CUSTOMERS 表,然后将其从数据库中删除,如下所示 -

SQL> DESC CUSTOMERS;
+---------+---------------+------+-----+---------+-------+
| Field   | Type          | Null | Key | Default | Extra |
+---------+---------------+------+-----+---------+-------+
| ID      | int(11)       | NO   | PRI |         |       |
| NAME    | varchar(20)   | NO   |     |         |       |
| AGE     | int(11)       | NO   |     |         |       |
| ADDRESS | char(25)      | YES  |     | NULL    |       |
| SALARY  | decimal(18,2) | YES  |     | NULL    |       |
+---------+---------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

这意味着 CUSTOMERS 表在数据库中可用,因此让我们现在将其删除,如下所示。

SQL> DROP TABLE CUSTOMERS;
Query OK, 0 rows affected (0.01 sec)

现在,如果您尝试使用 DESC 命令,则会收到以下错误 -

SQL> DESC CUSTOMERS;
ERROR 1146 (42S02): Table 'TEST.CUSTOMERS' doesn't exist

这里,TEST 是我们用于示例的数据库名称。

SQL - INSERT 查询

SQL INSERT INTO 语句用于向数据库中的表添加新的数据行。

语法

INSERT INTO 语句有两个基本语法,如下所示。

INSERT INTO TABLE_NAME (column1, column2, column3,...columnN)  
VALUES (value1, value2, value3,...valueN);

这里,column1、column2、column3...columnN 是您要向其中插入数据的表的列名。

如果您要为表的所有列添加值,则可能不需要在 SQL 查询中指定列名。但请确保值的顺序与表中列的顺序相同。

SQL INSERT INTO 语法如下 -

INSERT INTO TABLE_NAME VALUES (value1,value2,value3,...valueN);

示例

以下语句将在 CUSTOMERS 表中创建六条记录。

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Ramesh', 32, 'Ahmedabad', 2000.00 );

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (2, 'Khilan', 25, 'Delhi', 1500.00 );

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (3, 'kaushik', 23, 'Kota', 2000.00 );

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (4, 'Chaitali', 25, 'Mumbai', 6500.00 );

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (5, 'Hardik', 27, 'Bhopal', 8500.00 );

INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (6, 'Komal', 22, 'MP', 4500.00 );

您可以使用第二个语法在 CUSTOMERS 表中创建记录,如下所示。

INSERT INTO CUSTOMERS 
VALUES (7, 'Muffy', 24, 'Indore', 10000.00 );

所有上述语句将在 CUSTOMERS 表中生成以下记录,如下所示。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

使用另一个表填充一个表

您可以通过对另一个表执行 select 语句将数据填充到表中;前提是另一个表具有一组字段,这些字段是填充第一个表所需的。

语法如下 -

INSERT INTO first_table_name [(column1, column2, ... columnN)] 
   SELECT column1, column2, ...columnN 
   FROM second_table_name
   [WHERE condition];

SQL - SELECT 查询

SQL SELECT 语句用于从数据库表中提取数据,该数据以结果表的格式返回这些数据。这些结果表称为结果集。

语法

SELECT 语句的基本语法如下 -

SELECT column1, column2, columnN FROM table_name;

这里,column1、column2... 是您想要提取其值的表的字段。如果要提取字段中所有可用的字段,则可以使用以下语法。

SELECT * FROM table_name;

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下代码是一个示例,它将提取 CUSTOMERS 表中可用的客户的 ID、Name 和 Salary 字段。

SQL> SELECT ID, NAME, SALARY FROM CUSTOMERS;

这将产生以下结果 -

+----+----------+----------+
| ID | NAME     | SALARY   |
+----+----------+----------+
|  1 | Ramesh   |  2000.00 |
|  2 | Khilan   |  1500.00 |
|  3 | kaushik  |  2000.00 |
|  4 | Chaitali |  6500.00 |
|  5 | Hardik   |  8500.00 |
|  6 | Komal    |  4500.00 |
|  7 | Muffy    | 10000.00 |
+----+----------+----------+

如果要提取 CUSTOMERS 表的所有字段,则应使用以下查询。

SQL> SELECT * FROM CUSTOMERS;

这将产生如下所示的结果。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

SQL - WHERE 子句

SQL WHERE 子句用于在从单个表或通过连接多个表提取数据时指定条件。如果满足给定条件,则仅返回表中的特定值。您应该使用 WHERE 子句过滤记录并仅提取必要的记录。

WHERE 子句不仅用于 SELECT 语句,还用于 UPDATE、DELETE 语句等,我们将在后续章节中对其进行检查。

语法

带有 WHERE 子句的 SELECT 语句的基本语法如下所示。

SELECT column1, column2, columnN 
FROM table_name
WHERE [condition]

您可以使用比较或逻辑运算符(如 >、<、=、LIKE、NOT 等)指定条件。以下示例将使此概念更加清晰。

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下代码是一个示例,它将从 CUSTOMERS 表中提取 ID、Name 和 Salary 字段,其中 Salary 大于 2000 -

SQL> SELECT ID, NAME, SALARY 
FROM CUSTOMERS
WHERE SALARY > 2000;

这将产生以下结果 -

+----+----------+----------+
| ID | NAME     | SALARY   |
+----+----------+----------+
|  4 | Chaitali |  6500.00 |
|  5 | Hardik   |  8500.00 |
|  6 | Komal    |  4500.00 |
|  7 | Muffy    | 10000.00 |
+----+----------+----------+

以下查询是一个示例,它将从 CUSTOMERS 表中提取 ID、Name 和 Salary 字段,用于名称为 Hardik 的客户。

这里,需要注意的是,所有字符串都应放在单引号('')内。而数值应在没有任何引号的情况下给出,如上述示例所示。
SQL> SELECT ID, NAME, SALARY 
FROM CUSTOMERS
WHERE NAME = 'Hardik';

这将产生以下结果 -

+----+----------+----------+
| ID | NAME     | SALARY   |
+----+----------+----------+
|  5 | Hardik   |  8500.00 |
+----+----------+----------+

SQL - AND 和 OR 连接运算符

SQL AND & OR 运算符用于组合多个条件以缩小 SQL 语句中的数据范围。这两个运算符称为连接运算符。

这些运算符提供了一种方法,可以在同一个 SQL 语句中使用不同的运算符进行多次比较。

AND 运算符

AND 运算符允许 SQL 语句的 WHERE 子句中存在多个条件。

语法

带有 WHERE 子句的 AND 运算符的基本语法如下 -

SELECT column1, column2, columnN 
FROM table_name
WHERE [condition1] AND [condition2]...AND [conditionN];

您可以使用 AND 运算符组合 N 个条件。对于 SQL 语句要执行的操作,无论是事务还是查询,由 AND 分隔的所有条件都必须为 TRUE。

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是一个示例,它将从 CUSTOMERS 表中提取 ID、Name 和 Salary 字段,其中 Salary 大于 2000 且年龄小于 25 岁 -

SQL> SELECT ID, NAME, SALARY 
FROM CUSTOMERS
WHERE SALARY > 2000 AND age < 25;

这将产生以下结果 -

+----+-------+----------+
| ID | NAME  | SALARY   |
+----+-------+----------+
|  6 | Komal |  4500.00 |
|  7 | Muffy | 10000.00 |
+----+-------+----------+

OR 运算符

OR 运算符用于组合 SQL 语句的 WHERE 子句中的多个条件。

语法

带有 WHERE 子句的 OR 运算符的基本语法如下 -

SELECT column1, column2, columnN 
FROM table_name
WHERE [condition1] OR [condition2]...OR [conditionN]

您可以使用 OR 运算符组合 N 个条件。对于 SQL 语句要执行的操作,无论是事务还是查询,由 OR 分隔的条件中只有一个必须为 TRUE。

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下代码块包含一个查询,该查询将从 CUSTOMERS 表中提取 ID、Name 和 Salary 字段,其中 Salary 大于 2000 或年龄小于 25 岁。

SQL> SELECT ID, NAME, SALARY 
FROM CUSTOMERS
WHERE SALARY > 2000 OR age < 25;

这将产生以下结果 -

+----+----------+----------+
| ID | NAME     | SALARY   |
+----+----------+----------+
|  3 | kaushik  |  2000.00 |
|  4 | Chaitali |  6500.00 |
|  5 | Hardik   |  8500.00 |
|  6 | Komal    |  4500.00 |
|  7 | Muffy    | 10000.00 |
+----+----------+----------+

SQL - UPDATE 查询

SQL UPDATE 查询用于修改表中现有的记录。您可以将 WHERE 子句与 UPDATE 查询一起使用来更新选定的行,否则所有行都将受到影响。

语法

带有 WHERE 子句的 UPDATE 查询的基本语法如下 -

UPDATE table_name
SET column1 = value1, column2 = value2...., columnN = valueN
WHERE [condition];

您可以使用 AND 或 OR 运算符组合 N 个条件。

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下查询将更新表中 ID 号为 6 的客户的 ADDRESS。

SQL> UPDATE CUSTOMERS
SET ADDRESS = 'Pune'
WHERE ID = 6;

现在,CUSTOMERS 表将具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | Pune      |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

如果要修改 CUSTOMERS 表中的所有 ADDRESS 和 SALARY 列值,则不需要使用 WHERE 子句,因为 UPDATE 查询就足够了,如下面的代码块所示。

SQL> UPDATE CUSTOMERS
SET ADDRESS = 'Pune', SALARY = 1000.00;

现在,CUSTOMERS 表将具有以下记录 -

+----+----------+-----+---------+---------+
| ID | NAME     | AGE | ADDRESS | SALARY  |
+----+----------+-----+---------+---------+
|  1 | Ramesh   |  32 | Pune    | 1000.00 |
|  2 | Khilan   |  25 | Pune    | 1000.00 |
|  3 | kaushik  |  23 | Pune    | 1000.00 |
|  4 | Chaitali |  25 | Pune    | 1000.00 |
|  5 | Hardik   |  27 | Pune    | 1000.00 |
|  6 | Komal    |  22 | Pune    | 1000.00 |
|  7 | Muffy    |  24 | Pune    | 1000.00 |
+----+----------+-----+---------+---------+

SQL - DELETE 查询

SQL DELETE 查询用于从表中删除现有记录。

您可以将 WHERE 子句与 DELETE 查询一起使用来删除选定的行,否则所有记录都将被删除。

语法

带有 WHERE 子句的 DELETE 查询的基本语法如下 -

DELETE FROM table_name
WHERE [condition];

您可以使用 AND 或 OR 运算符组合 N 个条件。

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下代码包含一个查询,该查询将删除 ID 为 6 的客户。

SQL> DELETE FROM CUSTOMERS
WHERE ID = 6;

现在,CUSTOMERS 表将具有以下记录。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

如果要从 CUSTOMERS 表中删除所有记录,则不需要使用 WHERE 子句,DELETE 查询如下 -

SQL> DELETE FROM CUSTOMERS;

现在,CUSTOMERS 表将没有任何记录。

SQL - LIKE 子句

SQL LIKE 子句用于使用通配符运算符将值与类似值进行比较。有两种通配符与 LIKE 运算符一起使用。

  • 百分号 (%)
  • 下划线 (_)

百分号表示零个、一个或多个字符。下划线表示单个数字或字符。这些符号可以组合使用。

语法

% 和 _ 的基本语法如下 -

SELECT FROM table_name
WHERE column LIKE 'XXXX%'

or 

SELECT FROM table_name
WHERE column LIKE '%XXXX%'

or

SELECT FROM table_name
WHERE column LIKE 'XXXX_'

or

SELECT FROM table_name
WHERE column LIKE '_XXXX'

or

SELECT FROM table_name
WHERE column LIKE '_XXXX_'

您可以使用 AND 或 OR 运算符组合 N 个条件。这里,XXXX 可以是任何数值或字符串值。

示例

下表显示了一些示例,其中 WHERE 部分具有不同的 LIKE 子句以及 '%' 和 '_' 运算符 -

序号 语句 & 描述
1

WHERE SALARY LIKE '200%'

查找以 200 开头的任何值。

2

WHERE SALARY LIKE '%200%'

查找在任何位置包含 200 的任何值。

3

WHERE SALARY LIKE '_00%'

查找在第二个和第三个位置包含 00 的任何值。

4

WHERE SALARY LIKE '2_%_%'

查找以 2 开头且至少包含 3 个字符的任何值。

5

WHERE SALARY LIKE '%2'

查找以 2 结尾的任何值。

6

WHERE SALARY LIKE '_2%3'

查找在第二个位置包含 2 且以 3 结尾的任何值。

7

WHERE SALARY LIKE '2___3'

查找五位数中以 2 开头并以 3 结尾的任何值。

让我们举一个真实的例子,考虑 CUSTOMERS 表具有如下所示的记录。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是一个示例,它将显示 CUSTOMERS 表中的所有记录,其中 SALARY 以 200 开头。

SQL> SELECT * FROM CUSTOMERS
WHERE SALARY LIKE '200%';

这将产生以下结果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
+----+----------+-----+-----------+----------+

SQL - TOP、LIMIT 或 ROWNUM 子句

SQL TOP 子句用于从表中提取前 N 个或 X% 的记录。

注意 - 所有数据库都不支持 TOP 子句。例如,MySQL 使用 LIMIT 子句来提取有限数量的记录,而 Oracle 使用 ROWNUM 命令来提取有限数量的记录。

语法

带有 SELECT 语句的 TOP 子句的基本语法如下。

SELECT TOP number|percent column_name(s)
FROM table_name
WHERE [condition]

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下查询是 SQL 服务器上的一个示例,它将从 CUSTOMERS 表中提取前 3 条记录。

SQL> SELECT TOP 3 * FROM CUSTOMERS;

这将产生以下结果 -

+----+---------+-----+-----------+---------+
| ID | NAME    | AGE | ADDRESS   | SALARY  |
+----+---------+-----+-----------+---------+
|  1 | Ramesh  |  32 | Ahmedabad | 2000.00 |
|  2 | Khilan  |  25 | Delhi     | 1500.00 |
|  3 | kaushik |  23 | Kota      | 2000.00 |
+----+---------+-----+-----------+---------+

如果您使用的是 MySQL 服务器,则以下是一个等效的示例 -

SQL> SELECT * FROM CUSTOMERS
LIMIT 3;

这将产生以下结果 -

+----+---------+-----+-----------+---------+
| ID | NAME    | AGE | ADDRESS   | SALARY  |
+----+---------+-----+-----------+---------+
|  1 | Ramesh  |  32 | Ahmedabad | 2000.00 |
|  2 | Khilan  |  25 | Delhi     | 1500.00 |
|  3 | kaushik |  23 | Kota      | 2000.00 |
+----+---------+-----+-----------+---------+

如果您使用的是 Oracle 服务器,则以下代码块包含一个等效的示例。

SQL> SELECT * FROM CUSTOMERS
WHERE ROWNUM <= 3;

这将产生以下结果 -

+----+---------+-----+-----------+---------+
| ID | NAME    | AGE | ADDRESS   | SALARY  |
+----+---------+-----+-----------+---------+
|  1 | Ramesh  |  32 | Ahmedabad | 2000.00 |
|  2 | Khilan  |  25 | Delhi     | 1500.00 |
|  3 | kaushik |  23 | Kota      | 2000.00 |
+----+---------+-----+-----------+---------+

SQL - ORDER BY 子句

SQL ORDER BY 子句用于根据一个或多个列对数据进行升序或降序排序。某些数据库默认按升序对查询结果进行排序。

语法

ORDER BY 子句的基本语法如下 -

SELECT column-list 
FROM table_name 
[WHERE condition] 
[ORDER BY column1, column2, .. columnN] [ASC | DESC];

您可以在 ORDER BY 子句中使用多个列。请确保您用于排序的任何列都在列列表中。

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下代码块包含一个示例,它将按 NAME 和 SALARY 的升序对结果进行排序 -

SQL> SELECT * FROM CUSTOMERS
   ORDER BY NAME, SALARY;

这将产生以下结果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
+----+----------+-----+-----------+----------+

以下代码块包含一个示例,它将按 NAME 的降序对结果进行排序。

SQL> SELECT * FROM CUSTOMERS
   ORDER BY NAME DESC;

这将产生以下结果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
+----+----------+-----+-----------+----------+

SQL - Group By

SQL GROUP BY 子句与 SELECT 语句一起使用,将相同的数据排列成组。此 GROUP BY 子句位于 SELECT 语句中的 WHERE 子句之后,并且位于 ORDER BY 子句之前。

语法

以下代码块显示了 GROUP BY 子句的基本语法。GROUP BY 子句必须位于 WHERE 子句中的条件之后,并且如果使用 ORDER BY 子句,则必须位于 ORDER BY 子句之前。

SELECT column1, column2
FROM table_name
WHERE [ conditions ]
GROUP BY column1, column2
ORDER BY column1, column2

示例

假设 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

如果要了解每个客户的工资总额,则 GROUP BY 查询如下所示。

SQL> SELECT NAME, SUM(SALARY) FROM CUSTOMERS
   GROUP BY NAME;

这将产生以下结果 -

+----------+-------------+
| NAME     | SUM(SALARY) |
+----------+-------------+
| Chaitali |     6500.00 |
| Hardik   |     8500.00 |
| kaushik  |     2000.00 |
| Khilan   |     1500.00 |
| Komal    |     4500.00 |
| Muffy    |    10000.00 |
| Ramesh   |     2000.00 |
+----------+-------------+

现在,让我们看一个 CUSTOMERS 表具有以下包含重复名称的记录的表 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Ramesh   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | kaushik  |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

现在,如果要再次了解每个客户的工资总额,则 GROUP BY 查询如下所示 -

SQL> SELECT NAME, SUM(SALARY) FROM CUSTOMERS
   GROUP BY NAME;

这将产生以下结果 -

+---------+-------------+
| NAME    | SUM(SALARY) |
+---------+-------------+
| Hardik  |     8500.00 |
| kaushik |     8500.00 |
| Komal   |     4500.00 |
| Muffy   |    10000.00 |
| Ramesh  |     3500.00 |
+---------+-------------+

SQL - Distinct 关键字

SQL 的DISTINCT关键字与SELECT语句一起使用,用于消除所有重复记录并仅获取唯一记录。

在表中可能存在多个重复记录的情况。在获取此类记录时,获取唯一记录而不是获取重复记录更有意义。

语法

用于消除重复记录的DISTINCT关键字的基本语法如下所示:

SELECT DISTINCT column1, column2,.....columnN 
FROM table_name
WHERE [condition]

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

首先,让我们看看以下SELECT查询如何返回重复的工资记录。

SQL> SELECT SALARY FROM CUSTOMERS
   ORDER BY SALARY;

这将产生以下结果,其中工资(2000)出现了两次,这是原始表中的重复记录。

+----------+
| SALARY   |
+----------+
|  1500.00 |
|  2000.00 |
|  2000.00 |
|  4500.00 |
|  6500.00 |
|  8500.00 |
| 10000.00 |
+----------+

现在,让我们在上面的SELECT查询中使用DISTINCT关键字,然后查看结果。

SQL> SELECT DISTINCT SALARY FROM CUSTOMERS
   ORDER BY SALARY;

这将产生以下结果,其中我们没有任何重复条目。

+----------+
| SALARY   |
+----------+
|  1500.00 |
|  2000.00 |
|  4500.00 |
|  6500.00 |
|  8500.00 |
| 10000.00 |
+----------+

SQL - 排序结果

SQL ORDER BY 子句用于根据一个或多个列对数据进行升序或降序排序。某些数据库默认按升序对查询结果进行排序。

语法

用于按升序或降序排序结果的ORDER BY子句的基本语法如下所示:

SELECT column-list 
FROM table_name 
[WHERE condition] 
[ORDER BY column1, column2, .. columnN] [ASC | DESC];

您可以在ORDER BY子句中使用多个列。请确保您用于排序的任何列都必须在列列表中。

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是一个示例,它将按NAME和SALARY升序排序结果。

SQL> SELECT * FROM CUSTOMERS
   ORDER BY NAME, SALARY;

这将产生以下结果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
+----+----------+-----+-----------+----------+

以下代码块包含一个示例,它将按NAME降序排序结果。

SQL> SELECT * FROM CUSTOMERS
   ORDER BY NAME DESC;

这将产生以下结果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
+----+----------+-----+-----------+----------+

要按自己的首选顺序获取行,将使用以下SELECT查询:

SQL> SELECT * FROM CUSTOMERS
   ORDER BY (CASE ADDRESS
   WHEN 'DELHI' 	 THEN 1
   WHEN 'BHOPAL' 	 THEN 2
   WHEN 'KOTA' 	 THEN 3
   WHEN 'AHMEDABAD' THEN 4
   WHEN 'MP' 	THEN 5
   ELSE 100 END) ASC, ADDRESS DESC;

这将产生以下结果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
+----+----------+-----+-----------+----------+

这将根据您ownoOrder的首选项按ADDRESS对客户进行排序,并对其余地址按自然顺序排序。此外,其余地址将按反字母顺序排序。

SQL - 约束

约束是对表的数据列强制执行的规则。它们用于限制可以输入表的的数据类型。这确保了数据库中数据的准确性和可靠性。

约束可以是列级约束或表级约束。列级约束仅应用于一列,而表级约束应用于整个表。

以下是SQL中一些最常用的约束。这些约束已在SQL - RDBMS 概念章节中讨论过,但在这一点上值得复习。

  • NOT NULL 约束 - 确保列不能具有NULL值。

  • UNIQUE 约束 - 确保列中的所有值都不同。

  • 主键 - 唯一标识数据库表中的每一行/记录。

  • FOREIGN KEY - 唯一标识任何给定数据库表中的一行/记录。

  • 索引 - 用于非常快速地创建和检索数据库中的数据。

可以在创建表时使用CREATE TABLE语句指定约束,或者您也可以在创建表后使用ALTER TABLE语句创建约束。

删除约束

您可以使用ALTER TABLE命令和DROP CONSTRAINT选项删除已定义的任何约束。

例如,要删除EMPLOYEES表中的主键约束,可以使用以下命令。

ALTER TABLE EMPLOYEES DROP CONSTRAINT EMPLOYEES_PK;

某些实现可能提供删除某些约束的快捷方式。例如,要在Oracle中删除表的PrimaryKey约束,可以使用以下命令。

ALTER TABLE EMPLOYEES DROP PRIMARY KEY;

某些实现允许您禁用约束。与其永久地从数据库中删除约束,不如暂时禁用约束,然后稍后启用它。

完整性约束

完整性约束用于确保关系数据库中数据的准确性和一致性。关系数据库通过参照完整性的概念来处理数据完整性。

有许多类型的完整性约束在参照完整性 (RI)中发挥作用。这些约束包括主键、外键、唯一约束和其他上面提到的约束。

SQL - 使用连接

SQL 的Joins子句用于组合数据库中两个或多个表中的记录。JOIN 是一种通过使用每个表共有的值来组合两个表中的字段的方法。

考虑以下两个表:

表 1 - CUSTOMERS 表

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

表 2 - ORDERS 表

+-----+---------------------+-------------+--------+
|OID  | DATE                | CUSTOMER_ID | AMOUNT |
+-----+---------------------+-------------+--------+
| 102 | 2009-10-08 00:00:00 |           3 |   3000 |
| 100 | 2009-10-08 00:00:00 |           3 |   1500 |
| 101 | 2009-11-20 00:00:00 |           2 |   1560 |
| 103 | 2008-05-20 00:00:00 |           4 |   2060 |
+-----+---------------------+-------------+--------+

现在,让我们在SELECT语句中连接这两个表,如下所示。

SQL> SELECT ID, NAME, AGE, AMOUNT
   FROM CUSTOMERS, ORDERS
   WHERE  CUSTOMERS.ID = ORDERS.CUSTOMER_ID;

这将产生以下结果。

+----+----------+-----+--------+
| ID | NAME     | AGE | AMOUNT |
+----+----------+-----+--------+
|  3 | kaushik  |  23 |   3000 |
|  3 | kaushik  |  23 |   1500 |
|  2 | Khilan   |  25 |   1560 |
|  4 | Chaitali |  25 |   2060 |
+----+----------+-----+--------+

这里,可以注意到连接是在WHERE子句中执行的。可以使用多个运算符来连接表,例如=、<、>、<>、<=、>=、!=、BETWEEN、LIKE和NOT;它们都可以用于连接表。但是,最常见的运算符是等于符号。

SQL中有多种类型的连接:

  • INNER JOIN - 当两个表中都存在匹配项时返回行。

  • LEFT JOIN - 返回左侧表中的所有行,即使右侧表中没有匹配项。

  • RIGHT JOIN - 返回右侧表中的所有行,即使左侧表中没有匹配项。

  • FULL JOIN - 当其中一个表中存在匹配项时返回行。

  • SELF JOIN - 用于将表本身连接起来,就好像该表是两个表一样,在SQL语句中临时重命名至少一个表。

现在让我们详细讨论每个连接。

SQL - UNION 子句

SQL UNION 子句/运算符用于组合两个或多个SELECT语句的结果,而不返回任何重复行。

要使用此UNION子句,每个SELECT语句必须具有

  • 相同数量的选定列
  • 相同数量的列表达式
  • 相同的数据类型,并且
  • 按相同的顺序排列

但它们不必具有相同的长度。

语法

UNION子句的基本语法如下所示:

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

UNION

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

这里,给定的条件可以是基于您的需求的任何给定表达式。

示例

考虑以下两个表。

表 1 - CUSTOMERS 表如下所示。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

表 2 - ORDERS 表如下所示。

+-----+---------------------+-------------+--------+
|OID  | DATE                | CUSTOMER_ID | AMOUNT |
+-----+---------------------+-------------+--------+
| 102 | 2009-10-08 00:00:00 |           3 |   3000 |
| 100 | 2009-10-08 00:00:00 |           3 |   1500 |
| 101 | 2009-11-20 00:00:00 |           2 |   1560 |
| 103 | 2008-05-20 00:00:00 |           4 |   2060 |
+-----+---------------------+-------------+--------+

现在,让我们在SELECT语句中连接这两个表,如下所示:

SQL> SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   LEFT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
UNION
   SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   RIGHT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;

这将产生以下结果 -

+------+----------+--------+---------------------+
| ID   | NAME     | AMOUNT | DATE                |
+------+----------+--------+---------------------+
|    1 | Ramesh   |   NULL | NULL                |
|    2 | Khilan   |   1560 | 2009-11-20 00:00:00 |
|    3 | kaushik  |   3000 | 2009-10-08 00:00:00 |
|    3 | kaushik  |   1500 | 2009-10-08 00:00:00 |
|    4 | Chaitali |   2060 | 2008-05-20 00:00:00 |
|    5 | Hardik   |   NULL | NULL                |
|    6 | Komal    |   NULL | NULL                |
|    7 | Muffy    |   NULL | NULL                |
+------+----------+--------+---------------------+

UNION ALL 子句

UNION ALL运算符用于组合两个SELECT语句的结果,包括重复行。

应用于UNION子句的相同规则将应用于UNION ALL运算符。

语法

UNION ALL的基本语法如下所示。

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

UNION ALL

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

这里,给定的条件可以是基于您的需求的任何给定表达式。

示例

考虑以下两个表,

表 1 - CUSTOMERS 表如下所示。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

表 2 - ORDERS 表如下所示。

+-----+---------------------+-------------+--------+
|OID  | DATE                | CUSTOMER_ID | AMOUNT |
+-----+---------------------+-------------+--------+
| 102 | 2009-10-08 00:00:00 |           3 |   3000 |
| 100 | 2009-10-08 00:00:00 |           3 |   1500 |
| 101 | 2009-11-20 00:00:00 |           2 |   1560 |
| 103 | 2008-05-20 00:00:00 |           4 |   2060 |
+-----+---------------------+-------------+--------+

现在,让我们在SELECT语句中连接这两个表,如下所示:

SQL> SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   LEFT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID
UNION ALL
   SELECT  ID, NAME, AMOUNT, DATE
   FROM CUSTOMERS
   RIGHT JOIN ORDERS
   ON CUSTOMERS.ID = ORDERS.CUSTOMER_ID;

这将产生以下结果 -

+------+----------+--------+---------------------+
| ID   | NAME     | AMOUNT | DATE                |
+------+----------+--------+---------------------+
|    1 | Ramesh   |   NULL | NULL                |
|    2 | Khilan   |   1560 | 2009-11-20 00:00:00 |
|    3 | kaushik  |   3000 | 2009-10-08 00:00:00 |
|    3 | kaushik  |   1500 | 2009-10-08 00:00:00 |
|    4 | Chaitali |   2060 | 2008-05-20 00:00:00 |
|    5 | Hardik   |   NULL | NULL                |
|    6 | Komal    |   NULL | NULL                |
|    7 | Muffy    |   NULL | NULL                |
|    3 | kaushik  |   3000 | 2009-10-08 00:00:00 |
|    3 | kaushik  |   1500 | 2009-10-08 00:00:00 |
|    2 | Khilan   |   1560 | 2009-11-20 00:00:00 |
|    4 | Chaitali |   2060 | 2008-05-20 00:00:00 |
+------+----------+--------+---------------------+

还有另外两个子句(即运算符),它们类似于UNION子句。

  • SQL INTERSECT 子句 - 用于组合两个SELECT语句,但仅返回第一个SELECT语句中与第二个SELECT语句中的一行相同的行。

  • SQL EXCEPT 子句 - 组合两个SELECT语句并返回第一个SELECT语句中未由第二个SELECT语句返回的行。

SQL - NULL 值

SQL 的NULL是用于表示缺失值的术语。表中的NULL值是指字段中看起来为空白的值。

具有NULL值的字段是没有值的字段。务必了解,NULL值不同于零值或包含空格的字段。

语法

创建表时NULL的基本语法。

SQL> CREATE TABLE CUSTOMERS(
   ID   INT              NOT NULL,
   NAME VARCHAR (20)     NOT NULL,
   AGE  INT              NOT NULL,
   ADDRESS  CHAR (25) ,
   SALARY   DECIMAL (18, 2),       
   PRIMARY KEY (ID)
);

这里,NOT NULL表示列应始终接受给定数据类型的显式值。在两列中我们没有使用NOT NULL,这意味着这些列可以为NULL。

具有NULL值的字段是在记录创建期间留空的部分。

示例

NULL值在选择数据时可能会导致问题。但是,因为当将未知值与任何其他值进行比较时,结果始终是未知的并且不包含在结果中。您必须使用IS NULLIS NOT NULL运算符来检查NULL值。

考虑以下CUSTOMERS表,其中包含如下所示的记录。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |          |
|  7 | Muffy    |  24 | Indore    |          |
+----+----------+-----+-----------+----------+

现在,以下是IS NOT NULL运算符的用法。

SQL> SELECT  ID, NAME, AGE, ADDRESS, SALARY
   FROM CUSTOMERS
   WHERE SALARY IS NOT NULL;

这将产生以下结果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
+----+----------+-----+-----------+----------+

现在,以下是IS NULL运算符的用法。

SQL> SELECT  ID, NAME, AGE, ADDRESS, SALARY
   FROM CUSTOMERS
   WHERE SALARY IS NULL;

这将产生以下结果 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  6 | Komal    |  22 | MP        |          |
|  7 | Muffy    |  24 | Indore    |          |
+----+----------+-----+-----------+----------+

SQL - 别名语法

您可以通过赋予另一个称为别名的名称来临时重命名表或列。使用表别名的目的是在特定的SQL语句中重命名表。重命名是临时更改,实际的表名不会在数据库中更改。列别名用于重命名表的列,以便于特定的SQL查询。

语法

别名的基本语法如下所示。

SELECT column1, column2....
FROM table_name AS alias_name
WHERE [condition];

别名的基本语法如下所示。

SELECT column_name AS alias_name
FROM table_name
WHERE [condition];

示例

考虑以下两个表。

表 1 - CUSTOMERS 表如下所示。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

表 2 - ORDERS 表如下所示。

+-----+---------------------+-------------+--------+
|OID  | DATE                | CUSTOMER_ID | AMOUNT |
+-----+---------------------+-------------+--------+
| 102 | 2009-10-08 00:00:00 |           3 |   3000 |
| 100 | 2009-10-08 00:00:00 |           3 |   1500 |
| 101 | 2009-11-20 00:00:00 |           2 |   1560 |
| 103 | 2008-05-20 00:00:00 |           4 |   2060 |
+-----+---------------------+-------------+--------+

现在,以下代码块显示了表别名的用法。

SQL> SELECT C.ID, C.NAME, C.AGE, O.AMOUNT 
   FROM CUSTOMERS AS C, ORDERS AS O
   WHERE  C.ID = O.CUSTOMER_ID;

这将产生以下结果。

+----+----------+-----+--------+
| ID | NAME     | AGE | AMOUNT |
+----+----------+-----+--------+
|  3 | kaushik  |  23 |   3000 |
|  3 | kaushik  |  23 |   1500 |
|  2 | Khilan   |  25 |   1560 |
|  4 | Chaitali |  25 |   2060 |
+----+----------+-----+--------+

以下是列别名的用法。

SQL> SELECT  ID AS CUSTOMER_ID, NAME AS CUSTOMER_NAME
   FROM CUSTOMERS
   WHERE SALARY IS NOT NULL;

这将产生以下结果。

+-------------+---------------+
| CUSTOMER_ID | CUSTOMER_NAME |
+-------------+---------------+
|           1 | Ramesh        |
|           2 | Khilan        |
|           3 | kaushik       |
|           4 | Chaitali      |
|           5 | Hardik        |
|           6 | Komal         |
|           7 | Muffy         |
+-------------+---------------+

SQL - 索引

索引是数据库搜索引擎可以使用来加快数据检索速度的特殊查找表。简单来说,索引是指向表中数据的指针。数据库中的索引与书籍后面的索引非常相似。

例如,如果您想引用一本书中讨论某个特定主题的所有页面,您首先参考索引,该索引按字母顺序列出所有主题,然后参考一个或多个特定的页码。

索引有助于加快SELECT查询和WHERE子句的速度,但会降低数据输入速度,包括UPDATEINSERT语句。创建或删除索引不会影响数据。

创建索引涉及CREATE INDEX语句,该语句允许您命名索引,指定表以及要索引的列或列,并指示索引是按升序还是降序排列。

索引也可以是唯一的,就像UNIQUE约束一样,因为索引可以防止在存在索引的列或列组合中插入重复项。

CREATE INDEX 命令

CREATE INDEX的基本语法如下所示。

CREATE INDEX index_name ON table_name;

单列索引

单列索引是基于一个表列创建的。基本语法如下所示。

CREATE INDEX index_name
ON table_name (column_name);

唯一索引

唯一索引不仅用于性能,还用于数据完整性。唯一索引不允许将任何重复值插入表中。基本语法如下所示。

CREATE UNIQUE INDEX index_name
on table_name (column_name);

复合索引

复合索引是表中两列或多列上的索引。其基本语法如下所示。

CREATE INDEX index_name
on table_name (column1, column2);

无论创建单列索引还是复合索引,都要考虑在查询的WHERE子句中经常用作筛选条件的列。

如果只有一列使用,则应选择单列索引。如果在WHERE子句中经常使用两列或多列作为筛选器,则复合索引将是最佳选择。

隐式索引

隐式索引是在创建对象时由数据库服务器自动创建的索引。主键约束和唯一约束会自动创建索引。

DROP INDEX 命令

可以使用 SQL 的 **DROP** 命令删除索引。删除索引时应谨慎操作,因为这可能会导致性能下降或提升。

基本语法如下:

DROP INDEX index_name;

您可以查看 索引约束 章节以查看有关索引的一些实际示例。

何时应避免使用索引?

尽管索引旨在提高数据库的性能,但在某些情况下应避免使用它们。

以下指南说明了何时应重新考虑使用索引。

  • 不应在小型表上使用索引。

  • 频繁进行大量批量更新或插入操作的表。

  • 不应在包含大量 NULL 值的列上使用索引。

  • 不应为经常被修改的列建立索引。

SQL - ALTER TABLE 命令

SQL 的 **ALTER TABLE** 命令用于在现有表中添加、删除或修改列。您还应使用 ALTER TABLE 命令在现有表上添加和删除各种约束。

语法

在现有表中添加 **新列** 的 ALTER TABLE 命令的基本语法如下。

ALTER TABLE table_name ADD column_name datatype;

在现有表中 **删除列** 的 ALTER TABLE 命令的基本语法如下。

ALTER TABLE table_name DROP COLUMN column_name;

更改表中列的 **数据类型** 的 ALTER TABLE 命令的基本语法如下。

ALTER TABLE table_name MODIFY COLUMN column_name datatype;

在表中列上添加 **NOT NULL** 约束的 ALTER TABLE 命令的基本语法如下。

ALTER TABLE table_name MODIFY column_name datatype NOT NULL;

向表添加 **唯一约束** 的 ALTER TABLE 的基本语法如下。

ALTER TABLE table_name 
ADD CONSTRAINT MyUniqueConstraint UNIQUE(column1, column2...);

向表添加 **CHECK 约束** 的 ALTER TABLE 命令的基本语法如下。

ALTER TABLE table_name 
ADD CONSTRAINT MyUniqueConstraint CHECK (CONDITION);

向表添加 **主键** 约束的 ALTER TABLE 命令的基本语法如下。

ALTER TABLE table_name 
ADD CONSTRAINT MyPrimaryKey PRIMARY KEY (column1, column2...);

从表中 **删除约束** 的 ALTER TABLE 命令的基本语法如下。

ALTER TABLE table_name 
DROP CONSTRAINT MyUniqueConstraint;

如果您使用的是 MySQL,则代码如下:

ALTER TABLE table_name 
DROP INDEX MyUniqueConstraint;

从表中 **删除主键** 约束的 ALTER TABLE 命令的基本语法如下。

ALTER TABLE table_name 
DROP CONSTRAINT MyPrimaryKey;

如果您使用的是 MySQL,则代码如下:

ALTER TABLE table_name 
DROP PRIMARY KEY;

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是向现有表添加 **新列** 的示例:

ALTER TABLE CUSTOMERS ADD SEX char(1);

现在,CUSTOMERS 表已更改,以下将是 SELECT 语句的输出。

+----+---------+-----+-----------+----------+------+
| ID | NAME    | AGE | ADDRESS   | SALARY   | SEX  |
+----+---------+-----+-----------+----------+------+
|  1 | Ramesh  |  32 | Ahmedabad |  2000.00 | NULL |
|  2 | Ramesh  |  25 | Delhi     |  1500.00 | NULL |
|  3 | kaushik |  23 | Kota      |  2000.00 | NULL |
|  4 | kaushik |  25 | Mumbai    |  6500.00 | NULL |
|  5 | Hardik  |  27 | Bhopal    |  8500.00 | NULL |
|  6 | Komal   |  22 | MP        |  4500.00 | NULL |
|  7 | Muffy   |  24 | Indore    | 10000.00 | NULL |
+----+---------+-----+-----------+----------+------+

以下是从现有表中删除 sex 列的示例。

ALTER TABLE CUSTOMERS DROP SEX;

现在,CUSTOMERS 表已更改,以下将是 SELECT 语句的输出。

+----+---------+-----+-----------+----------+
| ID | NAME    | AGE | ADDRESS   | SALARY   |
+----+---------+-----+-----------+----------+
|  1 | Ramesh  |  32 | Ahmedabad |  2000.00 |
|  2 | Ramesh  |  25 | Delhi     |  1500.00 |
|  3 | kaushik |  23 | Kota      |  2000.00 |
|  4 | kaushik |  25 | Mumbai    |  6500.00 |
|  5 | Hardik  |  27 | Bhopal    |  8500.00 |
|  6 | Komal   |  22 | MP        |  4500.00 |
|  7 | Muffy   |  24 | Indore    | 10000.00 |
+----+---------+-----+-----------+----------+

SQL - TRUNCATE TABLE 命令

SQL 的 **TRUNCATE TABLE** 命令用于删除现有表中的所有数据。

您还可以使用 DROP TABLE 命令删除整个表,但这会从数据库中删除整个表结构,并且如果您希望存储一些数据,则需要重新创建此表。

语法

**TRUNCATE TABLE** 命令的基本语法如下。

TRUNCATE TABLE  table_name;

示例

假设 CUSTOMERS 表包含以下记录:

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是 Truncate 命令的示例。

SQL > TRUNCATE TABLE CUSTOMERS;

现在,CUSTOMERS 表已被截断,SELECT 语句的输出将如以下代码块所示:

SQL> SELECT * FROM CUSTOMERS;
Empty set (0.00 sec)

SQL - 使用视图

视图只不过是存储在数据库中并具有关联名称的 SQL 语句。视图实际上是以预定义的 SQL 查询形式组成的表。

视图可以包含表的全部行或表的选定行。视图可以从一个或多个表创建,这取决于用于创建视图的 SQL 查询。

视图是一种虚拟表,允许用户执行以下操作:

  • 以用户或用户类别认为自然或直观的方式组织数据。

  • 以这样一种方式限制对数据的访问:用户只能查看(有时)修改他们需要的内容,而不能查看更多内容。

  • 汇总来自各个表的的数据,这些数据可用于生成报表。

创建视图

数据库视图使用 **CREATE VIEW** 语句创建。视图可以从单个表、多个表或另一个视图创建。

要创建视图,用户必须根据特定实现拥有相应的系统权限。

基本的 **CREATE VIEW** 语法如下:

CREATE VIEW view_name AS
SELECT column1, column2.....
FROM table_name
WHERE [condition];

您可以像在普通 SQL SELECT 查询中使用它们一样,在 SELECT 语句中包含多个表。

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是如何从 CUSTOMERS 表创建视图的示例。此视图将用于获取 CUSTOMERS 表中的客户姓名和年龄。

SQL > CREATE VIEW CUSTOMERS_VIEW AS
SELECT name, age
FROM  CUSTOMERS;

现在,您可以像查询实际表一样查询 CUSTOMERS_VIEW。以下是一个示例。

SQL > SELECT * FROM CUSTOMERS_VIEW;

这将产生以下结果。

+----------+-----+
| name     | age |
+----------+-----+
| Ramesh   |  32 |
| Khilan   |  25 |
| kaushik  |  23 |
| Chaitali |  25 |
| Hardik   |  27 |
| Komal    |  22 |
| Muffy    |  24 |
+----------+-----+

WITH CHECK OPTION

WITH CHECK OPTION 是 CREATE VIEW 语句的一个选项。WITH CHECK OPTION 的目的是确保所有 UPDATE 和 INSERT 都满足视图定义中的条件。

如果它们不满足条件,则 UPDATE 或 INSERT 将返回错误。

以下代码块包含使用 WITH CHECK OPTION 创建相同视图 CUSTOMERS_VIEW 的示例。

CREATE VIEW CUSTOMERS_VIEW AS
SELECT name, age
FROM  CUSTOMERS
WHERE age IS NOT NULL
WITH CHECK OPTION;

在这种情况下,WITH CHECK OPTION 应该拒绝在视图的 AGE 列中输入任何 NULL 值,因为视图由 AGE 列中没有 NULL 值的数据定义。

更新视图

在某些条件下可以更新视图,这些条件如下:

  • SELECT 子句可能不包含 DISTINCT 关键字。

  • SELECT 子句可能不包含汇总函数。

  • SELECT 子句可能不包含集合函数。

  • SELECT 子句可能不包含集合运算符。

  • SELECT 子句可能不包含 ORDER BY 子句。

  • FROM 子句可能不包含多个表。

  • WHERE 子句可能不包含子查询。

  • 查询可能不包含 GROUP BY 或 HAVING。

  • 不能更新计算列。

  • 为了使 INSERT 查询正常工作,必须在视图中包含基表中的所有 NOT NULL 列。

因此,如果视图满足上述所有规则,则可以更新该视图。以下代码块包含更新 Ramesh 年龄的示例。

SQL > UPDATE CUSTOMERS_VIEW
   SET AGE = 35
   WHERE name = 'Ramesh';

这最终将更新基表 CUSTOMERS,并且更改将反映在视图本身中。现在,尝试查询基表,SELECT 语句将产生以下结果。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

向视图中插入行

可以向视图中插入数据行。适用于 UPDATE 命令的相同规则也适用于 INSERT 命令。

在这里,我们无法在 CUSTOMERS_VIEW 中插入行,因为我们没有在此视图中包含所有 NOT NULL 列,否则您可以像在表中插入行一样在视图中插入行。

从视图中删除行

可以从视图中删除数据行。适用于 UPDATE 和 INSERT 命令的相同规则也适用于 DELETE 命令。

以下是如何删除 AGE = 22 的记录的示例。

SQL > DELETE FROM CUSTOMERS_VIEW
   WHERE age = 22;

这最终将从基表 CUSTOMERS 中删除一行,并且更改将反映在视图本身中。现在,尝试查询基表,SELECT 语句将产生以下结果。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

删除视图

显然,如果不再需要视图,则需要一种方法来删除它。语法非常简单,如下所示:

DROP VIEW view_name;

以下是如何从 CUSTOMERS 表中删除 CUSTOMERS_VIEW 的示例。

DROP VIEW CUSTOMERS_VIEW;

SQL - Having 子句

**HAVING 子句** 使您能够指定过滤结果集中显示哪些组结果的条件。

WHERE 子句对选定的列设置条件,而 HAVING 子句对 GROUP BY 子句创建的组设置条件。

语法

以下代码块显示了查询中 HAVING 子句的位置。

SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY

HAVING 子句必须跟在查询中的 GROUP BY 子句之后,并且如果使用 ORDER BY 子句,还必须位于其前面。以下代码块包含包含 HAVING 子句的 SELECT 语句的语法:

SELECT column1, column2
FROM table1, table2
WHERE [ conditions ]
GROUP BY column1, column2
HAVING [ conditions ]
ORDER BY column1, column2

示例

假设 CUSTOMERS 表包含以下记录。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是一个示例,它将显示与年龄计数相似的记录,该记录大于或等于 2。

SQL > SELECT ID, NAME, AGE, ADDRESS, SALARY
FROM CUSTOMERS
GROUP BY age
HAVING COUNT(age) >= 2;

这将产生以下结果 -

+----+--------+-----+---------+---------+
| ID | NAME   | AGE | ADDRESS | SALARY  |
+----+--------+-----+---------+---------+
|  2 | Khilan |  25 | Delhi   | 1500.00 |
+----+--------+-----+---------+---------+

SQL - 事务

事务是在数据库上执行的工作单元。事务是按逻辑顺序完成的工作单元或序列,无论是用户手动执行还是由某种数据库程序自动执行。

事务是对数据库进行的一项或多项更改的传播。例如,如果您正在创建记录、更新记录或从表中删除记录,那么您就是在对该表执行事务。控制这些事务对于确保数据完整性和处理数据库错误非常重要。

实际上,您会将许多 SQL 查询组合成一个组,并将它们作为一个事务的一部分一起执行。

事务的属性

事务具有以下四个标准属性,通常用首字母缩写词 **ACID** 来表示。

  • **原子性** - 确保工作单元中的所有操作都成功完成。否则,事务将在发生故障时中止,并且所有先前操作都将回滚到其以前的状态。

  • **一致性** - 确保数据库在成功提交事务后正确更改状态。

  • **隔离性** - 使事务能够独立于彼此并透明地运行。

  • **持久性** - 确保提交事务的结果或效果在系统故障的情况下仍然存在。

事务控制

以下命令用于控制事务。

  • **COMMIT** - 保存更改。

  • **ROLLBACK** - 回滚更改。

  • **SAVEPOINT** - 在事务组中创建回滚点。

  • **SET TRANSACTION** - 为事务命名。

事务控制命令

事务控制命令仅与 **DML 命令** 一起使用,例如 - INSERT、UPDATE 和 DELETE。它们不能用于创建或删除表,因为这些操作会自动提交到数据库中。

COMMIT 命令

COMMIT 命令是用于将事务调用的更改保存到数据库的事务命令。

COMMIT 命令是用于将事务调用的更改保存到数据库的事务命令。COMMIT 命令将自上次 COMMIT 或 ROLLBACK 命令以来所有事务保存到数据库。

COMMIT 命令的语法如下。

COMMIT;

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

下面是一个示例,它将删除表中年龄等于 25 的所有记录,然后提交数据库中的更改。

SQL> DELETE FROM CUSTOMERS
   WHERE AGE = 25;
SQL> COMMIT;

因此,表中的两行将被删除,并且 SELECT 语句将产生以下结果。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

ROLLBACK 命令

ROLLBACK 命令是用于撤消尚未保存到数据库的事务的交易命令。此命令只能用于撤消自上次发出 COMMIT 或 ROLLBACK 命令以来的事务。

ROLLBACK 命令的语法如下所示:

ROLLBACK;

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下是一个示例,它将删除表中年龄等于 25 的所有记录,然后回滚数据库中的更改。

SQL> DELETE FROM CUSTOMERS
   WHERE AGE = 25;
SQL> ROLLBACK;

因此,删除操作不会影响表,并且 SELECT 语句将产生以下结果。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

SAVEPOINT 命令

SAVEPOINT 是事务中的一个点,您可以在该点将事务回滚到某个特定点,而无需回滚整个事务。

SAVEPOINT 命令的语法如下所示。

SAVEPOINT SAVEPOINT_NAME;

此命令仅用于在所有事务语句中创建 SAVEPOINT。ROLLBACK 命令用于撤消一组事务。

回滚到 SAVEPOINT 的语法如下所示。

ROLLBACK TO SAVEPOINT_NAME;

以下是一个示例,您计划从 CUSTOMERS 表中删除三个不同的记录。您希望在每次删除之前创建一个 SAVEPOINT,以便您可以随时回滚到任何 SAVEPOINT 以将相应的数据恢复到其原始状态。

示例

假设 CUSTOMERS 表包含以下记录。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下代码块包含一系列操作。

SQL> SAVEPOINT SP1;
Savepoint created.
SQL> DELETE FROM CUSTOMERS WHERE ID=1;
1 row deleted.
SQL> SAVEPOINT SP2;
Savepoint created.
SQL> DELETE FROM CUSTOMERS WHERE ID=2;
1 row deleted.
SQL> SAVEPOINT SP3;
Savepoint created.
SQL> DELETE FROM CUSTOMERS WHERE ID=3;
1 row deleted.

现在三个删除操作已经完成,假设您改变主意并决定回滚到您标识为 SP2 的 SAVEPOINT。由于 SP2 是在第一次删除后创建的,因此最后两次删除被撤消了:

SQL> ROLLBACK TO SP2;
Rollback complete.

请注意,由于您回滚到 SP2,因此只执行了第一次删除。

SQL> SELECT * FROM CUSTOMERS;
+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+
6 rows selected.

RELEASE SAVEPOINT 命令

RELEASE SAVEPOINT 命令用于删除您创建的 SAVEPOINT。

RELEASE SAVEPOINT 命令的语法如下。

RELEASE SAVEPOINT SAVEPOINT_NAME;

释放 SAVEPOINT 后,您将无法再使用 ROLLBACK 命令撤消自上次 SAVEPOINT 以来执行的事务。

SET TRANSACTION 命令

SET TRANSACTION 命令可用于启动数据库事务。此命令用于为后续的事务指定特性。例如,您可以将事务指定为只读或读写。

SET TRANSACTION 命令的语法如下所示。

SET TRANSACTION [ READ WRITE | READ ONLY ];

SQL - 通配符运算符

我们已经讨论过 SQL LIKE 运算符,它用于使用通配符运算符将值与类似值进行比较。

SQL 支持与 LIKE 运算符结合使用的两个通配符运算符,在下表中详细解释。

序号 通配符 & 描述
1

百分号 (%)

匹配一个或多个字符。

注意 - MS Access 使用星号 (*) 通配符而不是百分号 (%) 通配符。

2

下划线 (_)

匹配一个字符。

注意 - MS Access 使用问号 (?) 代替下划线 (_) 来匹配任何一个字符。

百分号表示零个、一个或多个字符。下划线表示单个数字或字符。这些符号可以组合使用。

语法

“%”和“_”运算符的基本语法如下所示。

SELECT * FROM table_name
WHERE column LIKE 'XXXX%'

or 

SELECT * FROM table_name
WHERE column LIKE '%XXXX%'

or

SELECT * FROM table_name
WHERE column LIKE 'XXXX_'

or

SELECT * FROM table_name
WHERE column LIKE '_XXXX'

or

SELECT * FROM table_name
WHERE column LIKE '_XXXX_'

您可以使用 AND 或 OR 运算符组合 N 个条件。这里,XXXX 可以是任何数字或字符串值。

示例

下表包含一些示例,其中 WHERE 部分具有不同的 LIKE 子句以及“%”和“_”运算符。

序号 语句 & 描述
1

WHERE SALARY LIKE '200%'

查找以 200 开头的任何值。

2

WHERE SALARY LIKE '%200%'

查找在任何位置包含 200 的任何值。

3

WHERE SALARY LIKE '_00%'

查找在第二个和第三个位置包含 00 的任何值。

4

WHERE SALARY LIKE '2_%_%'

查找以 2 开头且至少包含 3 个字符的任何值。

5

WHERE SALARY LIKE '%2'

查找以 2 结尾的任何值。

6

WHERE SALARY LIKE '_2%3'

查找在第二个位置包含 2 且以 3 结尾的任何值。

7

WHERE SALARY LIKE '2___3'

查找五位数中以 2 开头并以 3 结尾的任何值。

让我们举一个真实的例子,假设 CUSTOMERS 表具有以下记录。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

以下代码块是一个示例,它将显示 CUSTOMERS 表中所有 SALARY 以 200 开头的记录。

SQL> SELECT * FROM CUSTOMERS
WHERE SALARY LIKE '200%';

这将产生以下结果。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
+----+----------+-----+-----------+----------+

SQL - 日期函数

下表列出了通过 SQL 可用的所有重要日期和时间相关函数。您的 RDBMS 支持各种其他函数。给定列表基于 MySQL RDBMS。

序号 函数 & 描述
1 ADDDATE()

添加日期

2 ADDTIME()

添加时间

3 CONVERT_TZ()

从一个时区转换为另一个时区

4 CURDATE()

返回当前日期

5 CURRENT_DATE(),CURRENT_DATE

CURDATE() 的同义词

6 CURRENT_TIME(),CURRENT_TIME

CURTIME() 的同义词

7 CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP

NOW() 的同义词

8 CURTIME()

返回当前时间

9 DATE_ADD()

添加两个日期

10 DATE_FORMAT()

按照指定格式化日期

11 DATE_SUB()

减去两个日期

12 DATE()

提取日期或日期时间表达式的日期部分

13 DATEDIFF()

减去两个日期

14 DAY()

DAYOFMONTH() 的同义词

15 DAYNAME()

返回星期的名称

16 DAYOFMONTH()

返回月份中的日期 (1-31)

17 DAYOFWEEK()

返回参数的星期索引

18 DAYOFYEAR()

返回一年中的日期 (1-366)

19 EXTRACT

提取日期的一部分

20 FROM_DAYS()

将日期编号转换为日期

21 FROM_UNIXTIME()

将日期格式化为 UNIX 时间戳

22 HOUR()

提取小时

23 LAST_DAY

返回参数的月份的最后一天

24 LOCALTIME(),LOCALTIME

NOW() 的同义词

25 LOCALTIMESTAMP,LOCALTIMESTAMP()

NOW() 的同义词

26 MAKEDATE()

根据年份和一年中的日期创建日期

27 MAKETIME

MAKETIME()

28 MICROSECOND()

返回参数的微秒数

29 MINUTE()

返回参数的分钟数

30 MONTH()

返回传递的日期的月份

31 MONTHNAME()

返回月份的名称

32 NOW()

返回当前日期和时间

33 PERIOD_ADD()

将期间添加到年-月

34 PERIOD_DIFF()

返回期间之间的月数

35 QUARTER()

返回日期参数的季度

36 SEC_TO_TIME()

将秒转换为“HH:MM:SS”格式

37 SECOND()

返回秒数 (0-59)

38 STR_TO_DATE()

将字符串转换为日期

39 SUBDATE()

当使用三个参数调用时,SUBDATE() 是 DATE_SUB() 的同义词

40 SUBTIME()

减去时间

41 SYSDATE()

返回函数执行的时间

42 TIME_FORMAT()

格式化为时间

43 TIME_TO_SEC()

返回转换为秒的参数

44 TIME()

提取传递的表达式的时段部分

45 TIMEDIFF()

减去时间

46 TIMESTAMP()

如果只有一个参数,此函数将返回日期或日期时间表达式。如果有两个参数,则返回参数的和

47 TIMESTAMPADD()

将间隔添加到日期时间表达式

48 TIMESTAMPDIFF()

从日期时间表达式中减去一个间隔

49 TO_DAYS()

返回转换为天的日期参数

50 UNIX_TIMESTAMP()

返回 UNIX 时间戳

51 UTC_DATE()

返回当前 UTC 日期

52 UTC_TIME()

返回当前 UTC 时间

53 UTC_TIMESTAMP()

返回当前 UTC 日期和时间

54 WEEK()

返回星期数

55 WEEKDAY()

返回星期索引

56 WEEKOFYEAR()

返回日期的日历周 (1-53)

57 YEAR()

返回年份

58 YEARWEEK()

返回年份和星期

ADDDATE(date,INTERVAL expr unit), ADDDATE(expr,days)

当使用第二个参数的 INTERVAL 形式调用时,ADDDATE() 是 DATE_ADD() 的同义词。相关函数 SUBDATE() 是 DATE_SUB() 的同义词。有关 INTERVAL unit 参数的信息,请参阅 DATE_ADD() 的讨论。

mysql> SELECT DATE_ADD('1998-01-02', INTERVAL 31 DAY);
+---------------------------------------------------------+
| DATE_ADD('1998-01-02', INTERVAL 31 DAY)                 |
+---------------------------------------------------------+
| 1998-02-02                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT ADDDATE('1998-01-02', INTERVAL 31 DAY);
+---------------------------------------------------------+
| ADDDATE('1998-01-02', INTERVAL 31 DAY)                  |
+---------------------------------------------------------+
| 1998-02-02                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

当使用第二个参数的 days 形式调用时,MySQL 将其视为要添加到 expr 的整数天数。

mysql> SELECT ADDDATE('1998-01-02', 31);
+---------------------------------------------------------+
| DATE_ADD('1998-01-02', INTERVAL 31 DAY)                 |
+---------------------------------------------------------+
| 1998-02-02                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

ADDTIME(expr1,expr2)

ADDTIME() 将 expr2 添加到 expr1 并返回结果。expr1 是时间或日期时间表达式,而 expr2 是时间表达式。

mysql> SELECT ADDTIME('1997-12-31 23:59:59.999999','1 1:1:1.000002');
+---------------------------------------------------------+
| DATE_ADD('1997-12-31 23:59:59.999999','1 1:1:1.000002') |
+---------------------------------------------------------+
| 1998-01-02 01:01:01.000001                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

CONVERT_TZ(dt,from_tz,to_tz)

这会将日期时间值 dt 从 from_tz 给定的时区转换为 to_tz 给定的时区,并返回结果值。如果参数无效,此函数将返回 NULL。

mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
+---------------------------------------------------------+
| CONVERT_TZ('2004-01-01 12:00:00','GMT','MET')           |
+---------------------------------------------------------+
| 2004-01-01 13:00:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');
+---------------------------------------------------------+
| CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00')     |
+---------------------------------------------------------+
| 2004-01-01 22:00:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

CURDATE()

返回当前日期,格式为“YYYY-MM-DD”或 YYYYMMDD,具体取决于函数是在字符串中使用还是在数字上下文中使用。

mysql> SELECT CURDATE();
+---------------------------------------------------------+
| CURDATE()                                               |
+---------------------------------------------------------+
| 1997-12-15                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT CURDATE() + 0;
+---------------------------------------------------------+
| CURDATE() + 0                                           |
+---------------------------------------------------------+
| 19971215                                                |
+---------------------------------------------------------+
1 row in set (0.00 sec)

CURRENT_DATE 和 CURRENT_DATE()

CURRENT_DATE 和 CURRENT_DATE() 是 CURDATE() 的同义词

CURTIME()

返回当前时间,格式为“HH:MM:SS”或 HHMMSS,具体取决于函数是在字符串中使用还是在数字上下文中使用。该值以当前时区表示。

mysql> SELECT CURTIME();
+---------------------------------------------------------+
| CURTIME()                                               |
+---------------------------------------------------------+
| 23:50:26                                                |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT CURTIME() + 0;
+---------------------------------------------------------+
| CURTIME() + 0                                           |
+---------------------------------------------------------+
| 235026                                                  |
+---------------------------------------------------------+
1 row in set (0.00 sec)

CURRENT_TIME 和 CURRENT_TIME()

CURRENT_TIME 和 CURRENT_TIME() 是 CURTIME() 的同义词。

CURRENT_TIMESTAMP 和 CURRENT_TIMESTAMP()

CURRENT_TIMESTAMP 和 CURRENT_TIMESTAMP() 是 NOW() 的同义词。

DATE(expr)

提取日期或日期时间表达式 expr 的日期部分。

mysql> SELECT DATE('2003-12-31 01:02:03');
+---------------------------------------------------------+
| DATE('2003-12-31 01:02:03')                             |
+---------------------------------------------------------+
|  2003-12-31                                             |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DATEDIFF(expr1,expr2)

DATEDIFF() 返回 expr1 - expr2,表示从一个日期到另一个日期的天数。expr1 和 expr2 都是日期或日期和时间表达式。计算中仅使用值的日期部分。

mysql> SELECT DATEDIFF('1997-12-31 23:59:59','1997-12-30');
+---------------------------------------------------------+
| DATEDIFF('1997-12-31 23:59:59','1997-12-30')            |
+---------------------------------------------------------+
| 1                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DATE_ADD(date,INTERVAL expr unit), DATE_SUB(date,INTERVAL expr unit)

这些函数执行日期运算。date 是指定起始日期的 DATETIME 或 DATE 值。expr 是一个表达式,指定要添加到或从起始日期中减去的间隔值。expr 是一个字符串;它可以以“-”开头表示负间隔。

unit 是一个关键字,指示应如何解释表达式中的单位。

INTERVAL 关键字和 unit 说明符不区分大小写。

下表显示了每个 unit 值的 expr 参数的预期格式。

unit 值 预期 expr 格式
MICROSECOND MICROSECONDS
SECOND SECONDS
分钟 分钟
小时 小时
季度 季度
秒和微秒 '秒.微秒'
分钟和微秒 '分钟.微秒'
分钟和秒 '分钟:秒'
小时和微秒 '小时.微秒'
小时、分钟和秒 '小时:分钟:秒'
小时和分钟 '小时:分钟'
天和微秒 '天.微秒'
天、小时、分钟和秒 '天 小时:分钟:秒'
天、小时和分钟 '天 小时:分钟'
天和小时 '天 小时'
年和月 '年-月'

从 MySQL 5.0.0 版本开始提供季度的值。

mysql> SELECT DATE_ADD('1997-12-31 23:59:59', 
   -> INTERVAL '1:1' MINUTE_SECOND);
+---------------------------------------------------------+
| DATE_ADD('1997-12-31 23:59:59', INTERVAL...             |
+---------------------------------------------------------+
| 1998-01-01 00:01:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_ADD('1999-01-01', INTERVAL 1 HOUR);
+---------------------------------------------------------+
| DATE_ADD('1999-01-01', INTERVAL 1 HOUR)                 |
+---------------------------------------------------------+
| 1999-01-01 01:00:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DATE_FORMAT(日期,格式)

此命令根据格式字符串格式化日期值。

格式字符串中可以使用以下说明符。格式说明符字符前需要使用“%”字符。

序号说明符 & 描述
1

%a

缩写星期名称 (Sun..Sat)

2

%b

缩写月份名称 (Jan..Dec)

3

%c

月份,数字 (0..12)

4

%D

带英文后缀的月份日期 (0th, 1st, 2nd, 3rd, .)

5

%d

月份日期,数字 (00..31)

6

%e

月份日期,数字 (0..31)

7

%f

微秒 (000000..999999)

8

%H

小时 (00..23)

9

%h

小时 (01..12)

10

%I

小时 (01..12)

11

%i

分钟,数字 (00..59)

12

%j

一年中的第几天 (001..366)

13

%k

小时 (0..23)

14

%l

小时 (1..12)

15

%M

月份名称 (January..December)

16

%m

月份,数字 (00..12)

17

%p

AM 或 PM

18

%r

12 小时制时间 (hh:mm:ss 后跟 AM 或 PM)

19

%S

秒 (00..59)

20

%s

秒 (00..59)

21

%T

24 小时制时间 (hh:mm:ss)

22

%U

星期 (00..53),其中星期日是星期中的第一天

23

%u

星期 (00..53),其中星期一是星期中的第一天

24

%V

星期 (01..53),其中星期日是星期中的第一天;与 %X 一起使用

25

%v

星期 (01..53),其中星期一是星期中的第一天;与 %x 一起使用

26

%W

星期名称 (Sunday..Saturday)

27

%w

星期中的第几天 (0=星期日..6=星期六)

28

%X

星期所在的年份,其中星期日是星期中的第一天,数字,四位数字;与 %V 一起使用

29

%x

星期所在的年份,其中星期一是星期中的第一天,数字,四位数字;与 %v 一起使用

30

%Y

年份,数字,四位数字

31

%y

年份,数字 (两位数字)

32

%%

字面值 .%. 字符

33

%x

x,对于上面未列出的任何 .x.

mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
+---------------------------------------------------------+
| DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y')          |
+---------------------------------------------------------+
| Saturday October 1997                                   |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00'
   -> '%H %k %I %r %T %S %w');
+---------------------------------------------------------+
| DATE_FORMAT('1997-10-04 22:23:00.......                 |
+---------------------------------------------------------+
|  22 22 10 10:23:00 PM 22:23:00 00 6                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DATE_SUB(日期,INTERVAL 表达式 单位)

这与 DATE_ADD() 函数类似。

DAY(日期)

DAY() 是 DAYOFMONTH() 函数的同义词。

DAYNAME(日期)

返回日期的星期名称。

mysql> SELECT DAYNAME('1998-02-05');
+---------------------------------------------------------+
| DAYNAME('1998-02-05')                                   |
+---------------------------------------------------------+
| Thursday                                                |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DAYOFMONTH(日期)

返回日期的月份日期,范围为 0 到 31。

mysql> SELECT DAYOFMONTH('1998-02-03');
+---------------------------------------------------------+
| DAYOFMONTH('1998-02-03')                                |
+---------------------------------------------------------+
| 3                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DAYOFWEEK(日期)

返回日期的星期索引 (1 = 星期日,2 = 星期一,...,7 = 星期六)。这些索引值对应于 ODBC 标准。

mysql> SELECT DAYOFWEEK('1998-02-03');
+---------------------------------------------------------+
|DAYOFWEEK('1998-02-03')                                  |
+---------------------------------------------------------+
| 3                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

DAYOFYEAR(日期)

返回日期的一年中的第几天,范围为 1 到 366。

mysql> SELECT DAYOFYEAR('1998-02-03');
+---------------------------------------------------------+
| DAYOFYEAR('1998-02-03')                                 |
+---------------------------------------------------------+
| 34                                                      |
+---------------------------------------------------------+
1 row in set (0.00 sec)

EXTRACT(单位 FROM 日期)

EXTRACT() 函数使用与 DATE_ADD() 或 DATE_SUB() 相同类型的单位说明符,但从日期中提取部分而不是执行日期运算。

mysql> SELECT EXTRACT(YEAR FROM '1999-07-02');
+---------------------------------------------------------+
| EXTRACT(YEAR FROM '1999-07-02')                         |
+---------------------------------------------------------+
| 1999                                                    |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT EXTRACT(YEAR_MONTH FROM '1999-07-02 01:02:03');
+---------------------------------------------------------+
| EXTRACT(YEAR_MONTH FROM '1999-07-02 01:02:03')          |
+---------------------------------------------------------+
| 199907                                                  |
+---------------------------------------------------------+
1 row in set (0.00 sec)

FROM_DAYS(N)

给定一个日期编号 N,返回一个 DATE 值。

mysql> SELECT FROM_DAYS(729669);
+---------------------------------------------------------+
| FROM_DAYS(729669)                                       |
+---------------------------------------------------------+
| 1997-10-07                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

注意 - 在旧日期上谨慎使用 FROM_DAYS()。它不适用于格里历出现之前的日期值 (1582)。

FROM_UNIXTIME(unix 时间戳)

FROM_UNIXTIME(unix 时间戳,格式)

返回unix 时间戳参数的表示形式,作为“YYYY-MM-DD HH:MM:SS 或 YYYYMMDDHHMMSS 格式的值,具体取决于函数是在字符串中还是在数字上下文中使用。该值以当前时区表示。unix 时间戳参数是内部时间戳值,由UNIX_TIMESTAMP() 函数生成。

如果给定了格式,则结果将根据格式字符串进行格式化,格式字符串的使用方式与DATE_FORMAT() 函数条目中列出的一样。

mysql> SELECT FROM_UNIXTIME(875996580);
+---------------------------------------------------------+
| FROM_UNIXTIME(875996580)                                |
+---------------------------------------------------------+
| 1997-10-04 22:23:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

HOUR(时间)

返回时间的小时。对于一天中的时间值,返回值的范围为 0 到 23。但是,TIME 值的范围实际上要大得多,因此 HOUR 可以返回大于 23 的值。

mysql> SELECT HOUR('10:05:03');
+---------------------------------------------------------+
| HOUR('10:05:03')                                        |
+---------------------------------------------------------+
| 10                                                      |
+---------------------------------------------------------+
1 row in set (0.00 sec)

LAST_DAY(日期)

获取日期或日期时间值并返回对应月份的最后一天的值。如果参数无效,则返回 NULL。

mysql> SELECT LAST_DAY('2003-02-05');
+---------------------------------------------------------+
| LAST_DAY('2003-02-05')                                  |
+---------------------------------------------------------+
| 2003-02-28                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

LOCALTIME 和 LOCALTIME()

LOCALTIME 和 LOCALTIME() 是 NOW() 的同义词。

LOCALTIMESTAMP 和 LOCALTIMESTAMP()

LOCALTIMESTAMP 和 LOCALTIMESTAMP() 是 NOW() 的同义词。

MAKEDATE(年份,一年中的第几天)

给定年份和一年中的第几天值,返回一个日期。一年中的第几天值必须大于 0,否则结果将为 NULL。

mysql> SELECT MAKEDATE(2001,31), MAKEDATE(2001,32);
+---------------------------------------------------------+
| MAKEDATE(2001,31), MAKEDATE(2001,32)                    |
+---------------------------------------------------------+
| '2001-01-31', '2001-02-01'                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

MAKETIME(小时,分钟,秒)

根据小时、分钟和秒参数返回一个时间值。

mysql> SELECT MAKETIME(12,15,30);
+---------------------------------------------------------+
| MAKETIME(12,15,30)                                      |
+---------------------------------------------------------+
| '12:15:30'                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

MICROSECOND(表达式)

从时间或日期时间表达式 (表达式) 中返回微秒,作为 0 到 999999 范围内的数字。

mysql> SELECT MICROSECOND('12:00:00.123456');
+---------------------------------------------------------+
| MICROSECOND('12:00:00.123456')                          |
+---------------------------------------------------------+
| 123456                                                  |
+---------------------------------------------------------+
1 row in set (0.00 sec)

MINUTE(时间)

返回时间的分,范围为 0 到 59。

mysql> SELECT MINUTE('98-02-03 10:05:03');
+---------------------------------------------------------+
| MINUTE('98-02-03 10:05:03')                             |
+---------------------------------------------------------+
| 5                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

MONTH(日期)

返回日期的月份,范围为 0 到 12。

mysql> SELECT MONTH('1998-02-03')
+---------------------------------------------------------+
| MONTH('1998-02-03')                                     |
+---------------------------------------------------------+
| 2                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

MONTHNAME(日期)

返回日期的月份的全称。

mysql> SELECT MONTHNAME('1998-02-05');
+---------------------------------------------------------+
| MONTHNAME('1998-02-05')                                 |
+---------------------------------------------------------+
| February                                                |
+---------------------------------------------------------+
1 row in set (0.00 sec)

NOW()

返回当前日期和时间,作为“YYYY-MM-DD HH:MM:SS”或 YYYYMMDDHHMMSS 格式的值,具体取决于函数是在字符串中还是在数字上下文中使用。此值以当前时区表示。

mysql> SELECT NOW();
+---------------------------------------------------------+
| NOW()                                                   |
+---------------------------------------------------------+
| 1997-12-15 23:50:26                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

PERIOD_ADD(P,N)

向期间 P (格式为 YYMM 或 YYYYMM) 添加 N 个月。返回 YYYYMM 格式的值。请注意,期间参数 P 不是日期值。

mysql> SELECT PERIOD_ADD(9801,2);
+---------------------------------------------------------+
| PERIOD_ADD(9801,2)                                      |
+---------------------------------------------------------+
| 199803                                                  |
+---------------------------------------------------------+
1 row in set (0.00 sec)

PERIOD_DIFF(P1,P2)

返回期间 P1 和 P2 之间的月数。这些期间 P1 和 P2 应为 YYMM 或 YYYYMM 格式。请注意,期间参数 P1 和 P2 不是日期值。

mysql> SELECT PERIOD_DIFF(9802,199703);
+---------------------------------------------------------+
| PERIOD_DIFF(9802,199703)                                |
+---------------------------------------------------------+
| 11                                                      |
+---------------------------------------------------------+
1 row in set (0.00 sec)

QUARTER(日期)

返回日期所在年份的季度,范围为 1 到 4。

mysql> SELECT QUARTER('98-04-01');
+---------------------------------------------------------+
| QUARTER('98-04-01')                                     |
+---------------------------------------------------------+
| 2                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

SECOND(时间)

返回时间秒,范围为 0 到 59。

mysql> SELECT SECOND('10:05:03');
+---------------------------------------------------------+
| SECOND('10:05:03')                                      |
+---------------------------------------------------------+
| 3                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

SEC_TO_TIME(秒)

返回秒参数,转换为小时、分钟和秒,作为“HH:MM:SS”或 HHMMSS 格式的值,具体取决于函数是在字符串中还是在数字上下文中使用。

mysql> SELECT SEC_TO_TIME(2378);
+---------------------------------------------------------+
| SEC_TO_TIME(2378)                                       |
+---------------------------------------------------------+
| 00:39:38                                                |
+---------------------------------------------------------+
1 row in set (0.00 sec)

STR_TO_DATE(字符串,格式)

这是 DATE_FORMAT() 函数的反函数。它获取一个字符串 str 和一个格式字符串 format。如果格式字符串同时包含日期和时间部分,则 STR_TO_DATE() 函数返回一个 DATETIME 值。否则,如果字符串仅包含日期或时间部分,则返回 DATE 或 TIME 值。

mysql> SELECT STR_TO_DATE('04/31/2004', '%m/%d/%Y');
+---------------------------------------------------------+
| STR_TO_DATE('04/31/2004', '%m/%d/%Y')                   |
+---------------------------------------------------------+
| 2004-04-31                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

SUBDATE(日期,INTERVAL 表达式 单位) 和 SUBDATE(表达式,天)

当使用第二个参数的 INTERVAL 形式调用时,SUBDATE() 是 DATE_SUB() 的同义词。有关 INTERVAL 单位参数的信息,请参阅 DATE_ADD() 的讨论。

mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
+---------------------------------------------------------+
| DATE_SUB('1998-01-02', INTERVAL 31 DAY)                 |
+---------------------------------------------------------+
| 1997-12-02                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT SUBDATE('1998-01-02', INTERVAL 31 DAY);
+---------------------------------------------------------+
| SUBDATE('1998-01-02', INTERVAL 31 DAY)                  |
+---------------------------------------------------------+
| 1997-12-02                                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

SUBTIME(表达式1,表达式2)

SUBTIME() 函数返回表达式1 - 表达式2,表示为与表达式1 相同格式的值。表达式1 值是时间或日期时间表达式,而表达式2 值是时间表达式。

mysql> SELECT SUBTIME('1997-12-31 23:59:59.999999',
   -> '1 1:1:1.000002');
+---------------------------------------------------------+
| SUBTIME('1997-12-31 23:59:59.999999'...                 |
+---------------------------------------------------------+
| 1997-12-30 22:58:58.999997                              |
+---------------------------------------------------------+
1 row in set (0.00 sec)

SYSDATE()

返回当前日期和时间,作为“YYYY-MM-DD HH:MM:SS”或 YYYYMMDDHHMMSS 格式的值,具体取决于函数是在字符串中还是在数字上下文中使用。

mysql> SELECT SYSDATE();
+---------------------------------------------------------+
| SYSDATE()                                               |
+---------------------------------------------------------+
| 2006-04-12 13:47:44                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIME(表达式)

提取时间或日期时间表达式表达式的时间部分并将其作为字符串返回。

mysql> SELECT TIME('2003-12-31 01:02:03');
+---------------------------------------------------------+
| TIME('2003-12-31 01:02:03')                             |
+---------------------------------------------------------+
| 01:02:03                                                |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIMEDIFF(表达式1,表达式2)

TIMEDIFF() 函数返回表达式1 - 表达式2,表示为时间值。这些表达式1 和表达式2 值是时间或日期时间表达式,但两者必须为同一类型。

mysql> SELECT TIMEDIFF('1997-12-31 23:59:59.000001',
   -> '1997-12-30 01:01:01.000002');
+---------------------------------------------------------+
| TIMEDIFF('1997-12-31 23:59:59.000001'.....              |
+---------------------------------------------------------+
|  46:58:57.999999                                        |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIMESTAMP(表达式), TIMESTAMP(表达式1,表达式2)

使用单个参数时,此函数将日期或日期时间表达式表达式作为日期时间值返回。使用两个参数时,它将时间表达式表达式2 添加到日期或日期时间表达式表达式1 并将结果作为日期时间值返回。

mysql> SELECT TIMESTAMP('2003-12-31');
+---------------------------------------------------------+
| TIMESTAMP('2003-12-31')                                 |
+---------------------------------------------------------+
| 2003-12-31 00:00:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIMESTAMPADD(单位,间隔,日期时间表达式)

此函数将整数表达式间隔添加到日期或日期时间表达式日期时间表达式。间隔的单位由单位参数给出,该参数应为以下值之一 -

  • FRAC_SECOND
  • SECOND, MINUTE
  • HOUR, DAY
  • QUARTER 或

单位值可以使用所示的关键字之一或使用 SQL_TSI_ 前缀指定。

例如,DAY 和 SQL_TSI_DAY 都是合法的。

mysql> SELECT TIMESTAMPADD(MINUTE,1,'2003-01-02');
+---------------------------------------------------------+
| TIMESTAMPADD(MINUTE,1,'2003-01-02')                     |
+---------------------------------------------------------+
| 2003-01-02 00:01:00                                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIMESTAMPDIFF(单位,日期时间表达式1,日期时间表达式2)

返回日期或日期时间表达式日期时间表达式1 和日期时间表达式2 之间的整数差。结果的单位由单位参数给出。单位的合法值与 TIMESTAMPADD() 函数说明中列出的值相同。

mysql> SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');
+---------------------------------------------------------+
| TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01')          |
+---------------------------------------------------------+
| 3                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIME_FORMAT(时间,格式)

此函数的使用方式类似于 DATE_FORMAT() 函数,但格式字符串只能包含小时、分钟和秒的格式说明符。

如果时间值包含大于 23 的小时部分,则 %H 和 %k 小时格式说明符会生成大于 0 到 23 的通常范围的值。其他小时格式说明符生成小时值模 12。

mysql> SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l');
+---------------------------------------------------------+
| TIME_FORMAT('100:00:00', '%H %k %h %I %l')              |
+---------------------------------------------------------+
| 100 100 04 04 4                                         |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TIME_TO_SEC(时间)

返回转换为秒的时间参数。

mysql> SELECT TIME_TO_SEC('22:23:00');
+---------------------------------------------------------+
| TIME_TO_SEC('22:23:00')                                 |
+---------------------------------------------------------+
| 80580                                                   |
+---------------------------------------------------------+
1 row in set (0.00 sec)

TO_DAYS(日期)

给定一个日期,返回一个日期编号 (自公元 0 年以来的天数)。

mysql> SELECT TO_DAYS(950501);
+---------------------------------------------------------+
| TO_DAYS(950501)                                         |
+---------------------------------------------------------+
| 728779                                                  |
+---------------------------------------------------------+
1 row in set (0.00 sec)

UNIX_TIMESTAMP(), UNIX_TIMESTAMP(日期)

如果未带参数调用,则此函数返回一个 Unix 时间戳 (自“1970-01-01 00:00:00”UTC 以来经过的秒数) 作为无符号整数。如果使用日期参数调用 UNIX_TIMESTAMP(),则返回自“1970-01-01 00:00:00”UTC 以来参数的值(以秒为单位)。日期可以是 DATE 字符串、DATETIME 字符串、TIMESTAMP 或 YYMMDD 或 YYYYMMDD 格式的数字。

mysql> SELECT UNIX_TIMESTAMP();
+---------------------------------------------------------+
| UNIX_TIMESTAMP()                                        |
+---------------------------------------------------------+
| 882226357                                               |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT UNIX_TIMESTAMP('1997-10-04 22:23:00');
+---------------------------------------------------------+
| UNIX_TIMESTAMP('1997-10-04 22:23:00')                   |
+---------------------------------------------------------+
| 875996580                                               |
+---------------------------------------------------------+
1 row in set (0.00 sec)

UTC_DATE, UTC_DATE()

返回当前 UTC 日期,作为“YYYY-MM-DD”或 YYYYMMDD 格式的值,具体取决于函数是在字符串中还是在数字上下文中使用。

mysql> SELECT UTC_DATE(), UTC_DATE() + 0;
+---------------------------------------------------------+
| UTC_DATE(), UTC_DATE() + 0                              |
+---------------------------------------------------------+
| 2003-08-14, 20030814                                    |
+---------------------------------------------------------+
1 row in set (0.00 sec)

UTC_TIME, UTC_TIME()

返回当前 UTC 时间,作为“HH:MM:SS”或 HHMMSS 格式的值,具体取决于函数是在字符串中还是在数字上下文中使用。

mysql> SELECT UTC_TIME(), UTC_TIME() + 0;
+---------------------------------------------------------+
| UTC_TIME(), UTC_TIME() + 0                              |
+---------------------------------------------------------+
| 18:07:53, 180753                                        |
+---------------------------------------------------------+
1 row in set (0.00 sec)

UTC_TIMESTAMP, UTC_TIMESTAMP()

返回当前 UTC 日期和时间,作为“YYYY-MM-DD HH:MM:SS”或 YYYYMMDDHHMMSS 格式的值,具体取决于函数是在字符串中还是在数字上下文中使用。

mysql> SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;
+---------------------------------------------------------+
| UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0                    |
+---------------------------------------------------------+
| 2003-08-14 18:08:04, 20030814180804                     |
+---------------------------------------------------------+
1 row in set (0.00 sec)

WEEK(日期[,模式])

此函数返回日期的星期数。WEEK() 的双参数形式允许您指定星期是否从星期日或星期一开始,以及返回值是否应在 0 到 53 或 1 到 53 的范围内。如果省略 mode 参数,则使用 default_week_format 系统变量的值。

模式 一周的第一天 范围 第 1 周是第一周。
0 星期日 0-53 今年包含一个星期日
1 星期一 0-53 今年有超过 3 天
2 星期日 1-53 今年包含一个星期日
3 星期一 1-53 今年有超过 3 天
4 星期日 0-53 今年有超过 3 天
5 星期一 0-53 今年包含一个星期一
6 星期日 1-53 今年有超过 3 天
7 星期一 1-53 今年包含一个星期一
mysql> SELECT WEEK('1998-02-20');
+---------------------------------------------------------+
| WEEK('1998-02-20')                                      |
+---------------------------------------------------------+
| 7                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

WEEKDAY(date)

返回日期的星期几索引(0 = 星期一,1 = 星期二,... 6 = 星期日)。

mysql> SELECT WEEKDAY('1998-02-03 22:23:00');
+---------------------------------------------------------+
| WEEKDAY('1998-02-03 22:23:00')                          |
+---------------------------------------------------------+
| 1                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

WEEKOFYEAR(date)

将日期的日历周作为 1 到 53 范围内的数字返回。WEEKOFYEAR() 是一个兼容性函数,等效于 WEEK(date,3)。

mysql> SELECT WEEKOFYEAR('1998-02-20');
+---------------------------------------------------------+
| WEEKOFYEAR('1998-02-20')                                |
+---------------------------------------------------------+
| 8                                                       |
+---------------------------------------------------------+
1 row in set (0.00 sec)

YEAR(date)

返回日期的年份,范围为 1000 到 9999,或 0 表示零日期。

mysql> SELECT YEAR('98-02-03');
+---------------------------------------------------------+
| YEAR('98-02-03')                                        |
+---------------------------------------------------------+
| 1998                                                    |
+---------------------------------------------------------+
1 row in set (0.00 sec)

YEARWEEK(date), YEARWEEK(date,mode)

返回日期的年份和星期数。mode 参数的工作方式与 WEEK() 函数的 mode 参数完全相同。对于一年中的第一周和最后一周,结果中的年份可能与日期参数中的年份不同。

mysql> SELECT YEARWEEK('1987-01-01');
+---------------------------------------------------------+
| YEAR('98-02-03')YEARWEEK('1987-01-01')                  |
+---------------------------------------------------------+
| 198653                                                  |
+---------------------------------------------------------+
1 row in set (0.00 sec)

注意 - 对于可选参数 0 或 1,星期数与 WEEK() 函数返回的值(0)不同,因为 WEEK() 然后在给定年份的上下文中返回星期数。

SQL - 临时表

什么是临时表?

有一些 RDBMS 支持临时表。临时表是一个很棒的功能,它允许您存储和处理中间结果,方法是使用与典型 SQL Server 表相同的选择、更新和连接功能。

临时表在某些情况下可能非常有用,可以保存临时数据。关于临时表应该知道的最重要的一点是,当当前客户端会话终止时,它们将被删除。

MySQL 3.23 及更高版本中提供了临时表。如果您使用的 MySQL 版本早于 3.23,则无法使用临时表,但可以使用堆表

如前所述,临时表仅在会话处于活动状态时才会存在。如果您在 PHP 脚本中运行代码,则脚本执行完成后,临时表将自动销毁。如果您通过 MySQL 客户端程序连接到 MySQL 数据库服务器,则临时表将一直存在,直到您关闭客户端或手动销毁该表。

示例

以下是一个显示临时表用法的示例。

mysql> CREATE TEMPORARY TABLE SALESSUMMARY (
   -> product_name VARCHAR(50) NOT NULL
   -> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
   -> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
   -> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO SALESSUMMARY
   -> (product_name, total_sales, avg_unit_price, total_units_sold)
   -> VALUES
   -> ('cucumber', 100.25, 90, 2);

mysql> SELECT * FROM SALESSUMMARY;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
| cucumber     |      100.25 |          90.00 |                2 |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)

当您发出 SHOW TABLES 命令时,您的临时表将不会在列表中列出。现在,如果您退出 MySQL 会话,然后发出 SELECT 命令,您会发现数据库中没有可用数据。甚至您的临时表也将不存在。

删除临时表

默认情况下,当您的数据库连接终止时,所有临时表都将由 MySQL 删除。如果您想在中途删除它们,则可以通过发出DROP TABLE 命令来实现。

以下是删除临时表的示例。

mysql> CREATE TEMPORARY TABLE SALESSUMMARY (
   -> product_name VARCHAR(50) NOT NULL
   -> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
   -> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
   -> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO SALESSUMMARY
   -> (product_name, total_sales, avg_unit_price, total_units_sold)
   -> VALUES
   -> ('cucumber', 100.25, 90, 2);

mysql> SELECT * FROM SALESSUMMARY;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
| cucumber     |      100.25 |          90.00 |                2 |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)
mysql> DROP TABLE SALESSUMMARY;
mysql>  SELECT * FROM SALESSUMMARY;
ERROR 1146: Table 'TUTORIALS.SALESSUMMARY' doesn't exist

SQL - 克隆表

可能存在需要表的确切副本的情况,而 CREATE TABLE ... 或 SELECT... 命令不适合您的目的,因为副本必须包含相同的索引、默认值等。

如果您使用的是 MySQL RDBMS,则可以通过遵循以下步骤来处理这种情况:

  • 使用 SHOW CREATE TABLE 命令获取指定源表结构、索引等的 CREATE TABLE 语句。

  • 修改该语句以将表名更改为克隆表的表名,并执行该语句。这样,您将拥有一个完全克隆的表。

  • 可选地,如果您还需要复制表内容,则也发出 INSERT INTO 或 SELECT 语句。

示例

尝试以下示例为TUTORIALS_TBL 创建一个克隆表,其结构如下:

步骤 1 - 获取有关表的完整结构。

SQL> SHOW CREATE TABLE TUTORIALS_TBL \G; 
*************************** 1. row *************************** 
      Table: TUTORIALS_TBL 
Create Table: CREATE TABLE 'TUTORIALS_TBL' ( 
  'tutorial_id' int(11) NOT NULL auto_increment, 
  'tutorial_title' varchar(100) NOT NULL default '', 
  'tutorial_author' varchar(40) NOT NULL default '', 
  'submission_date' date default NULL, 
  PRIMARY KEY  ('tutorial_id'), 
  UNIQUE KEY 'AUTHOR_INDEX' ('tutorial_author') 
) TYPE = MyISAM 
1 row in set (0.00 sec)

步骤 2 - 重命名此表并创建另一个表。

SQL> CREATE TABLE `CLONE_TBL` ( 
  -> 'tutorial_id' int(11) NOT NULL auto_increment, 
  -> 'tutorial_title' varchar(100) NOT NULL default '', 
  -> 'tutorial_author' varchar(40) NOT NULL default '', 
  -> 'submission_date' date default NULL, 
  -> PRIMARY KEY  (`tutorial_id'), 
  -> UNIQUE KEY 'AUTHOR_INDEX' ('tutorial_author') 
-> ) TYPE = MyISAM; 
Query OK, 0 rows affected (1.80 sec) 

步骤 3 - 执行步骤 2 后,您将在数据库中克隆一个表。如果您想从旧表复制数据,则可以使用 INSERT INTO... SELECT 语句。

SQL> INSERT INTO CLONE_TBL (tutorial_id, 
   ->                        tutorial_title, 
   ->                        tutorial_author, 
   ->                        submission_date) 
   -> SELECT tutorial_id,tutorial_title, 
   ->        tutorial_author,submission_date, 
   -> FROM TUTORIALS_TBL; 
Query OK, 3 rows affected (0.07 sec) 
Records: 3  Duplicates: 0  Warnings: 0 

最后,您将获得您想要的完全克隆表。

SQL - 子查询

子查询或内部查询或嵌套查询是在另一个 SQL 查询中的查询,并嵌入在 WHERE 子句中。

子查询用于返回将在主查询中用作条件的数据,以进一步限制要检索的数据。

子查询可以与 SELECT、INSERT、UPDATE 和 DELETE 语句以及 =、<、>、>=、<=、IN、BETWEEN 等运算符一起使用。

子查询必须遵循一些规则:

  • 子查询必须括在括号中。

  • 子查询在 SELECT 子句中只能有一列,除非主查询中有多列供子查询比较其选定的列。

  • 虽然主查询可以使用 ORDER BY,但在子查询中不能使用 ORDER BY 命令。GROUP BY 命令可以用于执行与子查询中的 ORDER BY 相同的功能。

  • 返回多行的子查询只能与多值运算符(如 IN 运算符)一起使用。

  • SELECT 列表不能包含任何引用计算结果为 BLOB、ARRAY、CLOB 或 NCLOB 的值的引用。

  • 子查询不能立即包含在集合函数中。

  • BETWEEN 运算符不能与子查询一起使用。但是,可以在子查询中使用 BETWEEN 运算符。

带有 SELECT 语句的子查询

子查询最常与 SELECT 语句一起使用。基本语法如下:

SELECT column_name [, column_name ]
FROM   table1 [, table2 ]
WHERE  column_name OPERATOR
   (SELECT column_name [, column_name ]
   FROM table1 [, table2 ]
   [WHERE])

示例

考虑 CUSTOMERS 表具有以下记录 -

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

现在,让我们检查以下带有 SELECT 语句的子查询。

SQL> SELECT * 
   FROM CUSTOMERS 
   WHERE ID IN (SELECT ID 
         FROM CUSTOMERS 
         WHERE SALARY > 4500) ;

这将产生以下结果。

+----+----------+-----+---------+----------+
| ID | NAME     | AGE | ADDRESS | SALARY   |
+----+----------+-----+---------+----------+
|  4 | Chaitali |  25 | Mumbai  |  6500.00 |
|  5 | Hardik   |  27 | Bhopal  |  8500.00 |
|  7 | Muffy    |  24 | Indore  | 10000.00 |
+----+----------+-----+---------+----------+

带有 INSERT 语句的子查询

子查询也可以与 INSERT 语句一起使用。INSERT 语句使用子查询返回的数据插入到另一个表中。子查询中选定的数据可以使用任何字符、日期或数字函数进行修改。

基本语法如下。

INSERT INTO table_name [ (column1 [, column2 ]) ]
   SELECT [ *|column1 [, column2 ]
   FROM table1 [, table2 ]
   [ WHERE VALUE OPERATOR ]

示例

假设有一个与 CUSTOMERS 表结构类似的 CUSTOMERS_BKP 表。现在要将完整的 CUSTOMERS 表复制到 CUSTOMERS_BKP 表中,可以使用以下语法。

SQL> INSERT INTO CUSTOMERS_BKP
   SELECT * FROM CUSTOMERS 
   WHERE ID IN (SELECT ID 
   FROM CUSTOMERS) ;

带有 UPDATE 语句的子查询

子查询可以与 UPDATE 语句结合使用。使用子查询与 UPDATE 语句结合时,可以更新表中的单个或多个列。

基本语法如下。

UPDATE table
SET column_name = new_value
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

示例

假设我们有 CUSTOMERS_BKP 表可用,它是 CUSTOMERS 表的备份。以下示例将 CUSTOMERS 表中所有年龄大于或等于 27 的客户的 SALARY 更新为 0.25 倍。

SQL> UPDATE CUSTOMERS
   SET SALARY = SALARY * 0.25
   WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP
      WHERE AGE >= 27 );

这将影响两行,最后 CUSTOMERS 表将包含以下记录。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |   125.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  2125.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

带有 DELETE 语句的子查询

子查询可以与 DELETE 语句结合使用,就像上面提到的任何其他语句一样。

基本语法如下。

DELETE FROM TABLE_NAME
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

示例

假设我们有 CUSTOMERS_BKP 表可用,它是 CUSTOMERS 表的备份。以下示例从 CUSTOMERS 表中删除所有年龄大于或等于 27 的客户的记录。

SQL> DELETE FROM CUSTOMERS
   WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP
      WHERE AGE >= 27 );

这将影响两行,最后 CUSTOMERS 表将包含以下记录。

+----+----------+-----+---------+----------+
| ID | NAME     | AGE | ADDRESS | SALARY   |
+----+----------+-----+---------+----------+
|  2 | Khilan   |  25 | Delhi   |  1500.00 |
|  3 | kaushik  |  23 | Kota    |  2000.00 |
|  4 | Chaitali |  25 | Mumbai  |  6500.00 |
|  6 | Komal    |  22 | MP      |  4500.00 |
|  7 | Muffy    |  24 | Indore  | 10000.00 |
+----+----------+-----+---------+----------+

SQL - 使用序列

序列是一组整数 1、2、3、...,它们按需按顺序生成。序列在数据库中经常使用,因为许多应用程序要求表中的每一行都包含一个唯一值,而序列提供了一种生成它们的方法。

本章介绍如何在 MySQL 中使用序列。

使用 AUTO_INCREMENT 列

在 MySQL 中使用序列的最简单方法是将列定义为 AUTO_INCREMENT,并将其余操作留给 MySQL 处理。

示例

尝试以下示例。这将创建一个表,然后在此表中插入几行,其中不需要提供记录 ID,因为它是 MySQL 自动递增的。

mysql> CREATE TABLE INSECT
   -> (
   -> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
   -> PRIMARY KEY (id),
   -> name VARCHAR(30) NOT NULL, # type of insect
   -> date DATE NOT NULL, # date collected
   -> origin VARCHAR(30) NOT NULL # where collected
);
Query OK, 0 rows affected (0.02 sec)
mysql> INSERT INTO INSECT (id,name,date,origin) VALUES
   -> (NULL,'housefly','2001-09-10','kitchen'),
   -> (NULL,'millipede','2001-09-10','driveway'),
   -> (NULL,'grasshopper','2001-09-10','front yard');
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> SELECT * FROM INSECT ORDER BY id;
+----+-------------+------------+------------+
| id | name        | date       | origin     |
+----+-------------+------------+------------+
|  1 | housefly    | 2001-09-10 | kitchen    |
|  2 | millipede   | 2001-09-10 | driveway   |
|  3 | grasshopper | 2001-09-10 | front yard |
+----+-------------+------------+------------+
3 rows in set (0.00 sec)

获取 AUTO_INCREMENT 值

LAST_INSERT_ID( ) 是一个 SQL 函数,因此您可以在任何了解如何发出 SQL 语句的客户端中使用它。否则,PERL 和 PHP 脚本提供了检索最后一条记录的自动递增值的专属函数。

PERL 示例

使用mysql_insertid 属性获取查询生成的 AUTO_INCREMENT 值。此属性可以通过数据库句柄或语句句柄访问,具体取决于您发出查询的方式。以下示例通过数据库句柄引用它。

$dbh->do ("INSERT INTO INSECT (name,date,origin)
VALUES('moth','2001-09-14','windowsill')");
my $seq = $dbh->{mysql_insertid};

PHP 示例

发出生成 AUTO_INCREMENT 值的查询后,通过调用mysql_insert_id( ) 函数检索该值。

mysql_query ("INSERT INTO INSECT (name,date,origin)
VALUES('moth','2001-09-14','windowsill')", $conn_id);
$seq = mysql_insert_id ($conn_id);

重新编号现有序列

可能存在从表中删除了许多记录并且您想重新排序所有记录的情况。这可以通过使用一个简单的技巧来完成,但是您应该非常小心地执行此操作,并检查您的表是否与另一个表具有连接关系。

如果您确定重新排序 AUTO_INCREMENT 列是不可避免的,则执行此操作的方法是从表中删除该列,然后再次添加它。

以下示例说明如何使用此技术重新编号 insect 表中的 id 值。

mysql> ALTER TABLE INSECT DROP id;
mysql> ALTER TABLE insect
   -> ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
   -> ADD PRIMARY KEY (id);

从特定值开始序列

默认情况下,MySQL 将从 1 开始序列,但您也可以在创建表时指定任何其他数字。

以下代码块包含一个示例,其中 MySQL 将从 100 开始序列。

mysql> CREATE TABLE INSECT
   -> (
   -> id INT UNSIGNED NOT NULL AUTO_INCREMENT = 100,
   -> PRIMARY KEY (id),
   -> name VARCHAR(30) NOT NULL, # type of insect
   -> date DATE NOT NULL, # date collected
   -> origin VARCHAR(30) NOT NULL # where collected
);

或者,您可以创建表,然后使用 ALTER TABLE 设置初始序列值。

mysql> ALTER TABLE t AUTO_INCREMENT = 100;

SQL - 处理重复项

可能存在表中有多条重复记录的情况。在获取此类记录时,获取唯一记录而不是获取重复记录更有意义。

我们已经讨论过的 SQLDISTINCT 关键字与 SELECT 语句一起使用以消除所有重复记录,并仅获取唯一记录。

语法

消除重复记录的 DISTINCT 关键字的基本语法如下。

SELECT DISTINCT column1, column2,.....columnN 
FROM table_name
WHERE [condition]

示例

假设 CUSTOMERS 表包含以下记录。

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  32 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

首先,让我们看看以下 SELECT 查询是如何返回重复的工资记录的。

SQL> SELECT SALARY FROM CUSTOMERS
   ORDER BY SALARY;

这将产生以下结果,其中 2000 的工资出现了两次,这是原始表中的重复记录。

+----------+
| SALARY   |
+----------+
|  1500.00 |
|  2000.00 |
|  2000.00 |
|  4500.00 |
|  6500.00 |
|  8500.00 |
| 10000.00 |
+----------+

现在,让我们在上面的 SELECT 查询中使用 DISTINCT 关键字并查看结果。

SQL> SELECT DISTINCT SALARY FROM CUSTOMERS
   ORDER BY SALARY;

这将产生以下结果,其中我们没有任何重复条目。

+----------+
| SALARY   |
+----------+
|  1500.00 |
|  2000.00 |
|  4500.00 |
|  6500.00 |
|  8500.00 |
| 10000.00 |
+----------+

SQL - 注入

如果您通过网页获取用户输入并将其插入 SQL 数据库,则您有可能让自己面临一个称为SQL 注入的安全问题。本章将教您如何帮助防止这种情况发生,并帮助您保护服务器端脚本(如 PERL 脚本)中的脚本和 SQL 语句。

注入通常发生在您要求用户输入信息(如他们的姓名)时,并且他们给您的不是姓名,而是一个您会在不知情的情况下在数据库上运行的 SQL 语句。永远不要信任用户提供的数据,只有在验证后才处理这些数据;作为规则,这是通过模式匹配完成的。

在下面的示例中,name 限制为字母数字字符加上下划线,长度在 8 到 20 个字符之间(根据需要修改这些规则)。

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) {
   $result = mysql_query("SELECT * FROM CUSTOMERS 
      WHERE name = $matches[0]");
} else {
   echo "user name not accepted";
}

为了演示问题,请考虑以下摘录:

// supposed input
$name = "Qadir'; DELETE FROM CUSTOMERS;";
mysql_query("SELECT * FROM CUSTOMSRS WHERE name='{$name}'");

函数调用应该从 CUSTOMERS 表中检索一条记录,其中 name 列与用户指定的 name 匹配。在正常情况下,$name 只包含字母数字字符以及可能的空间,例如字符串 ilia。但是在这里,通过将一个全新的查询附加到 $name,对数据库的调用变成了灾难;注入的 DELETE 查询删除了 CUSTOMERS 表中的所有记录。

幸运的是,如果您使用 MySQL,mysql_query() 函数不允许查询堆叠或在单个函数调用中执行多个 SQL 查询。如果您尝试堆叠查询,则调用会失败。

但是,其他 PHP 数据库扩展(例如 SQLitePostgreSQL)会愉快地执行堆叠查询,执行一个字符串中提供的所有查询,并造成严重的安全问题。

防止 SQL 注入

您可以在 PERL 和 PHP 等脚本语言中巧妙地处理所有转义字符。PHP 的 MySQL 扩展提供了函数 mysql_real_escape_string() 来转义对 MySQL 具有特殊意义的输入字符。

if (get_magic_quotes_gpc()) {
   $name = stripslashes($name);
}
$name = mysql_real_escape_string($name);
mysql_query("SELECT * FROM CUSTOMERS WHERE name='{$name}'");

LIKE 难题

为了解决 LIKE 难题,自定义转义机制必须将用户提供的“%”和“_”字符转换为字面量。使用 addcslashes(),这是一个允许您指定要转义的字符范围的函数。

$sub = addcslashes(mysql_real_escape_string("%str"), "%_");
// $sub == \%str\_
mysql_query("SELECT * FROM messages 
   WHERE subject LIKE '{$sub}%'");

SQL - 数据库调优

成为数据库专家或专家数据库管理员需要时间。这都来自于在各种数据库设计和良好培训方面的丰富经验。

但是,以下列表可能对初学者获得良好的数据库性能有所帮助:

  • 使用本教程中 RDBMS 概念章节中解释的 3BNF 数据库设计。

  • 避免数字到字符的转换,因为数字和字符的比较方式不同,会导致性能下降。

  • 在使用 SELECT 语句时,仅获取所需的信息,并避免在 SELECT 查询中使用 *,因为它会不必要地加载系统。

  • 在所有频繁进行搜索操作的表上小心地创建索引。避免在搜索操作较少且插入和更新操作较多的表上创建索引。

  • 当 WHERE 子句中的列没有关联的索引时,会发生全表扫描。您可以通过在用作 WHERE 子句中 SQL 语句条件的列上创建索引来避免全表扫描。

  • 对实数和日期/时间值使用相等运算符要非常小心。这两者都可能存在肉眼无法察觉的小差异,但这些差异会导致精确匹配变得不可能,从而阻止您的查询返回任何行。

  • 谨慎使用模式匹配。LIKE COL% 是一个有效的 WHERE 条件,将返回集缩小到仅以字符串 COL 开头的那些记录。但是,COL%Y 不会进一步缩小返回的结果集,因为 %Y 无法有效评估。进行评估的努力太大,无法考虑。在这种情况下,将使用 COL%,但 %Y 将被丢弃。出于同样的原因,前导通配符 %COL 会有效地阻止整个过滤器被使用。

  • 微调您的 SQL 查询,检查查询(和子查询)的结构,SQL 语法,以发现您是否已设计表以支持快速数据操作并以最佳方式编写了查询,从而允许您的 DBMS 高效地操作数据。

  • 对于定期执行的查询,尝试使用过程。过程是一组可能很大的 SQL 语句。过程由数据库引擎编译,然后执行。与 SQL 语句不同,数据库引擎无需在执行过程之前对其进行优化。

  • 如果可能,避免在查询中使用逻辑运算符 OR。OR 不可避免地会减慢针对大尺寸表的几乎任何查询的速度。

  • 您可以通过删除索引来优化批量数据加载。想象一下具有数千行的历史表。该历史表也可能有一个或多个索引。当您想到索引时,通常会想到更快的表访问,但在批量加载的情况下,您可以通过删除索引来获益。

  • 在执行批处理事务时,在创建一定数量的记录后执行 COMMIT,而不是在创建每条记录后执行。

  • 计划定期对数据库进行碎片整理,即使这样做意味着开发每周例程。

内置调优工具

Oracle 有许多用于管理 SQL 语句性能的工具,但其中两个非常流行。这两个工具是:

  • Explain plan - 该工具识别执行 SQL 语句时将采用的访问路径。

  • tkprof - 通过 SQL 语句处理每个阶段经过的时间来衡量性能。

如果您只想在 Oracle 中测量查询的经过时间,可以使用 SQL*Plus 命令 SET TIMING ON。

有关上述工具和数据库碎片整理的更多详细信息,请查看您的 RDBMS 文档。

广告