Sql 简明教程

SQL - Quick Guide

SQL - Overview

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

What is SQL?

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

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

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

  1. MS SQL Server 使用 T-SQL,

  2. Oracle using PL/SQL,

  3. MS Access 版本的 SQL 称为 JET SQL(本机格式)等。

Why SQL?

SQL 广受欢迎,因为它提供了以下优势:

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

  2. 允许用户描述数据。

  3. 允许用户定义数据库中的数据并处理这些数据。

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

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

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

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

A Brief History of SQL

  1. 1970 − IBM 的埃德加·F·“泰德”·科德博士被称为关系型数据库之父。他描述了一种用于数据库的关系模型。

  2. 1974 - 出现了结构化查询语言。

  3. 1978 − IBM 致力于开发科德的想法,并发布了一款名为 System/R 的产品。

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

SQL Process

当你为任何 RDBMS 执行 SQL 命令时,系统会确定执行你的请求的最佳方式,而 SQL 引擎会弄清楚如何解释该任务。

此过程中包含多个组件。

这些组件包括:

  1. Query Dispatcher

  2. Optimization Engines

  3. Classic Query Engine

  4. SQL Query Engine, etc.

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

以下是一个简单的图表,显示了 SQL 架构:

sql architecture

SQL Commands

与关系数据库交互的标准 SQL 命令包括 CREATE、SELECT、INSERT、UPDATE、DELETE 和 DROP。根据其特性,可以将这些命令归类为以下组:

DDL - Data Definition Language

Sr.No.

Command & Description

1

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

2

ALTER 修改现有的数据库对象(例如,表)。

3

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

DML - Data Manipulation Language

Sr.No.

Command & Description

1

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

2

INSERT Creates a record.

3

UPDATE Modifies records.

4

DELETE Deletes records.

DCL - Data Control Language

Sr.No.

Command & Description

1

GRANT 赋予用户特权。

2

REVOKE 收回从用户授予的特权。

SQL - RDBMS Concepts

What is RDBMS?

RDBMS 代表 *R*elational *D*atabase *M*anagement *S*ystem。RDBMS 是 SQL 和所有现代数据库系统(例如 MS SQL Server、IBM DB2、Oracle、MySQL 和 Microsoft Access)的基础。

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

What is a table?

RDBMS 中的数据存储在称为 tables 的数据库对象中。此表基本上是相关数据项的集合,它由多个列和行组成。

请记住,表是关系型数据库中供数据存储的最基本和最常见的形式。下列程序是 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 |
+----+----------+-----+-----------+----------+

What is a field?

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

字段是表中专门用于维护表中每条记录的特定信息的列。

What is a Record or a Row?

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

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

记录是表中的水平实体。

What is a column?

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

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

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

What is a NULL value?

表中的 NULL 值是字段中看似空白的值,这意味着带有 NULL 值的字段是没有值。

了解 NULL 值与零值或包含空格的字段之间的不同非常重要。带有 NULL 值的字段是记录创建期间留空的字段。

SQL Constraints

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

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

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

  1. NOT NULL Constraint − 确保列不能有 NULL 值。

  2. UNIQUE Constraint − 确保列中所有值都不同。

  3. PRIMARY Key − 唯一标识数据库表中的每行/记录。

  4. FOREIGN Key − 在任何其他数据库表中唯一标识一组/记录。

  5. INDEX − 用于非常快速地从数据库中创建和提取数据。

Data Integrity

每个 RDBMS 都有以下数据完整性类别 −

  1. Entity Integrity − 表中没有重复的行。

  2. Domain Integrity − 通过限制类型、格式或值范围来强制执行给定列的有效项。

  3. Referential integrity − 无法删除被其他记录使用的行。

  4. User-Defined Integrity − 强制执行一些特定的业务规则,不属于实体、域或引用完整性规则。

Database Normalization

数据库范式化是有效组织数据库中数据的过程。此范式化过程有以下两个原因 −

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

  2. 确保数据依赖关系合理。

这两个原因都是有价值的目标,因为它们减少了数据库消耗的空间,并确保数据以逻辑方式存储。范式化包含一系列指南,可帮助您创建良好的数据库结构。

范式化准则分为范式;将范式视为数据库结构的格式或布局方式。范式旨在组织数据库结构,以便符合第一范式的规则,然后是第二范式,最后是第三范式。

您选择更进一步,进入第四范式、第五范式等,但通常情况下,第三范式已经足够了。

SQL - RDBMS Databases

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

MySQL

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

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

MySQL 具有免费和付费版本,具体取决于其用法(非商业/商业)和特性。MySQL 附带一个非常快速、多线程、多用户且稳定的 SQL 数据库服务器。

History

  1. 迈克尔·维德纽斯和戴维·阿克斯马克于1994年开始开发MySQL。

  2. 首次内部发布是在1995年5月23日。

  3. Windows版本于1998年1月8日为Windows 95和NT发布。

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

  5. 版本4.0: 2002年8月测试版,2003年3月正式发布(并集)。

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

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

  8. Sun Microsystems于2008年2月26日收购MySQL AB。

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

Features

  1. High Performance.

  2. High Availability.

  3. 可扩展性和灵活性,运行任何事物。

  4. Robust Transactional Support.

  5. Web和数据仓库优势。

  6. Strong Data Protection.

  7. Comprehensive Application Development.

  8. Management Ease.

  9. 开源自由和24 x 7支持。

  10. 总体拥有成本最低。

MS SQL Server

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

  1. T-SQL

  2. ANSI SQL

History

  1. 1987年-Sybase为UNIX发布SQL Server。

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

  3. 1989年-Microsoft,Sybase和Aston-Tate为OS/2发布SQL Server 1.0。

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

  5. Aston-Tate退出SQL Server开发。

  6. 2000 年 - Microsoft 发布 SQL Server 2000。

  7. 2001 年 - Microsoft 发布 SQL Server Web Release 1(下载)中的 XML。

  8. 2002 年 - Microsoft 发布 SQLXML 2.0(更名为 SQL Server 中的 XML)。

  9. 2002 年 - Microsoft 发布 SQLXML 3.0。

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

Features

  1. High Performance

  2. High Availability

  3. Database mirroring

  4. Database snapshots

  5. CLR integration

  6. Service Broker

  7. DDL triggers

  8. Ranking functions

  9. Row version-based isolation levels

  10. XML integration

  11. TRY…​CATCH

  12. Database Mail

ORACLE

它是一个非常庞大的多用户基于数据库管理系统。Oracle 是由“Oracle 公司”开发的关系数据库管理系统。

Oracle 能够高效管理其资源,在网络中发送和请求数据的众多客户中的一个信息数据库。

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

History

Oracle 于 1977 年创立,在业内庆祝其 32 个美好的年头(从 1977 年到 2009 年)。

  1. 1977 年 - 拉里·埃里森、鲍勃·迈纳和埃德·奥茨共同创立了软件研发实验室,从事开发工作。

  2. 1979 年 - Oracle 的 2.0 版本发布,成为第一个商业关系数据库以及第一个 SQL 数据库。该公司更名为关系软件公司 (RSI)。

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

  4. 1982 年 - RSI 更名为 Oracle Corporation。

  5. 1983 年 - Oracle 发布 3.0 版本,使用 C 语言重新编写,可在多个平台上运行。

  6. 1984 年 - Oracle version 4.0 发布。它包含并发控制、多版本读取一致性等功能。

  7. 1985 年 - Oracle version 4.0 发布。它包含并发控制、多版本读取一致性等功能。

  8. 2007 年 - Oracle 发布 Oracle11g。新版本重点在于更好的分区、轻松迁移等。

Features

  1. Concurrency

  2. Read Consistency

  3. Locking Mechanisms

  4. Quiesce Database

  5. Portability

  6. Self-managing database

  7. SQL*Plus

  8. ASM

  9. Scheduler

  10. Resource Manager

  11. Data Warehousing

  12. Materialized views

  13. Bitmap indexes

  14. Table compression

  15. Parallel Execution

  16. Analytic SQL

  17. Data mining

  18. Partitioning

MS ACCESS

这是最流行的 Microsoft 产品之一。Microsoft Access 是一款入门级数据库管理软件。MS Access 数据库不仅价格低廉,而且是小规模项目的强大数据库。

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

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

  1. 1992 - 发布了 Access 1.0 版本。

  2. 1993 - 发布 Access 1.1 来提高兼容性,并包含 Access Basic 编程语言。

  3. 最重要的过渡是从 Access 97 到 Access 2000。

  4. 2007 - Access 2007 引入了新的数据库格式 ACCDB,它支持多值和附件字段等复杂数据类型。

Features

  1. 用户可以创建表、查询、窗体和报表,并用宏将其连接在一起。

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

  3. 还有 Jet 数据库格式 (Access 2007 中为 MDB 或 ACCDB),它可以在一个文件中包含应用程序和数据。这使得向另一位用户分发整个应用程序变得非常方便,后者可以在断开连接的环境中运行它。

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

  5. 可以将 Microsoft SQL Server 的桌面版本与 Access 一起使用作为 Jet 数据库引擎的替代品。

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

SQL - Syntax

SQL 遵循一组称为语法的规则和指南。本教程通过列出所有基本的 SQL 语法快速入门 SQL。

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

这里需要特别注意的一点是,SQL 不区分大小写,这意味着 SELECT 和 select 在 SQL 语句中具有相同的含义。而 MySQL 在表名中会区分大小写。所以,如果您使用的是 MySQL,那么您需要根据数据库中存在的表名来提供表名。

Various Syntax in SQL

SQL SELECT Statement

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

SQL DISTINCT Clause

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

SQL WHERE Clause

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

SQL AND/OR Clause

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

SQL IN Clause

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

SQL BETWEEN Clause

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

SQL LIKE Clause

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

SQL ORDER BY Clause

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

SQL GROUP BY Clause

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

SQL COUNT Clause

SELECT COUNT(column_name)
FROM   table_name
WHERE  CONDITION;

SQL HAVING Clause

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

SQL CREATE TABLE Statement

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

SQL DROP TABLE Statement

DROP TABLE table_name;

SQL CREATE INDEX Statement

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

SQL DROP INDEX Statement

ALTER TABLE table_name
DROP INDEX index_name;

SQL DESC Statement

DESC table_name;

SQL TRUNCATE TABLE Statement

TRUNCATE TABLE table_name;

SQL ALTER TABLE Statement

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

SQL ALTER TABLE Statement (Rename)

ALTER TABLE table_name RENAME TO new_table_name;

SQL INSERT INTO Statement

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

SQL UPDATE Statement

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

SQL DELETE Statement

DELETE FROM table_name
WHERE  {CONDITION};

SQL CREATE DATABASE Statement

CREATE DATABASE database_name;

SQL DROP DATABASE Statement

DROP DATABASE database_name;

SQL USE Statement

USE database_name;

SQL COMMIT Statement

COMMIT;

SQL ROLLBACK Statement

ROLLBACK;

SQL - Data Types

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

SQL Server 为您提供了六类数据类型,如下所示:

Exact Numeric Data Types

DATA TYPE

FROM

TO

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

Approximate Numeric Data Types

DATA TYPE

FROM

TO

float

-1.79E + 308

1.79E + 308

real

-3.40E + 38

3.40E + 38

Date and Time Data Types

DATA TYPE

FROM

TO

datetime

Jan 1, 1753

Dec 31, 9999

smalldatetime

Jan 1, 1900

Jun 6, 2079

date

存储诸如 1991 年 6 月 30 日之类的日期

time

Note − 在此处,datetime 的精度为 3.33 毫秒,而 smalldatetime 的精度为 1 分钟。

Character Strings Data Types

Sr.No.

DATA TYPE & Description

1

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

2

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

3

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

4

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

Unicode Character Strings Data Types

Sr.No.

DATA TYPE & Description

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)。

Binary Data Types

Sr.No.

DATA TYPE & Description

1

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

2

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

3

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

4

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

Misc Data Types

Sr.No.

DATA TYPE & Description

1

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

2

timestamp 存储每次更新一行都会更新的数据库范围的唯一数字

3

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

4

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

5

cursor 对游标对象的引用

6

table 存储结果集以供以后处理

SQL - Operators

What is an Operator in SQL?

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

  1. Arithmetic operators

  2. Comparison operators

  3. Logical operators

  4. 用于否定条件的运算符

SQL Arithmetic Operators

假设 'variable a' 保存 10,而 'variable b' 保存 20,那么-

Operator

Description

Example

+ (Addition)

对运算符两边的值求和。

a + b 将得到 30

- (Subtraction)

从左操作数中减去右操作数。

a - b 将得到 -10

* (Multiplication)

对运算符两边的值求积。

a * b 将得到 200

/ (Division)

将左操作数除以右操作数。

b / a 将得到 2

% (Modulus)

将左操作数除以右操作数并返回余数。

b % a 将得到 0

SQL Comparison Operators

假设 'variable a' 保存 10,而 'variable b' 保存 20,那么-

Operator

Description

Example

=

检查两个操作数的值是否相等,如果相等,则条件变为真。

(a = b) 不为真。

!=

检查两个操作数的值是否相等,如果值不相等,则条件变为真。

(a != b) 为 true。

<>

检查两个操作数的值是否相等,如果值不相等,则条件变为真。

(a <> b) 为真。

>

检查左操作数的值是否大于右操作数的值,如果大于,则条件变为真。

(a > b) 为 false。

<

检查左操作数的值是否小于右操作数的值,如果小于,则条件变为真。

(a < b) 为 true。

>=

检查左操作数的值是否大于或等于右操作数的值,如果大于或等于,则条件变为真。

(a >= b) 为 false。

检查左操作数的值是否小于或等于右操作数的值,如果小于或等于,则条件变为真。

(a ⇐ b) 为 true。

!<

检查左操作数的值是否不小于右操作数的值,如果是,则条件为真。

(a !< b) 为假。

!>

检查左操作数的值是否不大于右操作数的值,如果是,则条件为真。

(a !> b) 为真。

SQL Logical Operators

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

Sr.No.

Operator & Description

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 等。 This is a negate operator.

9

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

10

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

11

UNIQUE UNIQUE 操作符搜索指定表的每行以查找唯一性(没有重复项)。

SQL - Expressions

表达式是一个或多个值、运算符和计算为值的 SQL 函数的组合。这些 SQL 表达式类似于公式,并且是用查询语言编写的。您还可以使用它们对数据库进行查询以获取一组特定数据。

Syntax

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

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

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

  1. Boolean

  2. Numeric

  3. Date

让我们现在详细讨论每一个这些。

Boolean Expressions

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)

Numeric Expression

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

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)

Date Expressions

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

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 - CREATE Database

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

Syntax

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

CREATE DATABASE DatabaseName;

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

Example

如果你想创建一个新数据库 <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 - DROP or DELETE Database

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

Syntax

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

DROP DATABASE DatabaseName;

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

Example

如果你想删除现有数据库 <testDB>,则 DROP DATABASE 语句如下所示:

SQL> DROP DATABASE testDB;

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

在删除任何数据库之前,请确保你拥有管理员权限。一旦删除一个数据库,你可以按照如下方式在数据库列表中查看:

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

SQL - SELECT Database, USE Statement

如果你的 SQL 模式中有多个数据库,那么在开始操作之前,你需要选择一个要执行所有操作的数据库。

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

Syntax

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

USE DatabaseName;

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

Example

你可以按照如下方式查看可用数据库:

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 - CREATE Table

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

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

Syntax

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 语句的组合来创建现有表的副本。你可以在 Create Table Using another Table. 处查看完整详细信息

Example

以下代码块是一个示例,它创建了一个带有主键 ID 的 CUSTOMERS 表,其中 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 - DROP or DELETE Table

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

NOTE − 使用此命令时应非常小心,因为一旦某个表被删除,该表中可用的所有信息也将永远丢失。

Syntax

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

DROP TABLE table_name;

Example

让我们首先验证 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 Query

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

Syntax

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);

Example

以下语句将在 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 |
+----+----------+-----+-----------+----------+

Populate one table using another table

您可以通过某一表的 select 语句将数据填充到另一张表中;前提是该另一张表具有第一张表所填充字段的一组字段。

以下是语法 −

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

SQL - SELECT Query

SQL SELECT 语句用于从数据库表中获取数据,该数据将以结果表的形式返回。这些结果表被称作结果集。

Syntax

SELECT 语句的基本语法如下所示 −

SELECT column1, column2, columnN FROM table_name;

此处,column1、column2…​ 是您想要获取其值的表字段。如果您想获取字段中可用所有字段,则可以使用以下语法。

SELECT * FROM table_name;

Example

考虑包含以下记录的 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 Clause

SQL WHERE 子句用于在从单个表中获取数据或通过与多个表进行联接时指定条件。如果满足给定的条件,则只会从表中返回特定值。您应使用 WHERE 子句来筛选记录并仅获取必要的记录。

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

Syntax

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

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

您可以使用 comparison or logical operators 之类 >、<、=、 LIKE, NOT 等条件来指定条件。以下示例将阐明此概念。

Example

考虑包含以下记录的 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 字段,其中薪水大于 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 and OR Conjunctive Operators

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

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

The AND Operator

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

Syntax

AND 运算符与 WHERE 子句组合后的基本语法如下 −

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

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

Example

考虑包含以下记录的 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 字段,其中薪水大于 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 |
+----+-------+----------+

The OR Operator

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

Syntax

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

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

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

Example

考虑包含以下记录的 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 字段,其中薪水大于 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 Query

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

Syntax

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

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

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

Example

考虑包含以下记录的 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 Query

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

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

Syntax

使用 WHERE 子句的 DELETE 查询的基本语法如下:

DELETE FROM table_name
WHERE [condition];

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

Example

考虑包含以下记录的 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 |
+----+----------+-----+-----------+----------+

下面的代码包含一个查询,该查询将 DELETE 一个其 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 表中 DELETE 所有记录,则无需使用 WHERE 子句,DELETE 查询如下所示:

SQL> DELETE FROM CUSTOMERS;

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

SQL - LIKE Clause

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

  1. The percent sign (%)

  2. The underscore (_)

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

Syntax

% 和 _ 的基本语法如下:

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 可以是任何数字或字符串值。

Example

下表列出了一些示例,其中 WHERE 部分具有带有 '%' 和 '_' 运算符的不同 LIKE 子句:

Sr.No.

Statement & Description

1

{s1} 查找以 200 开头的任何值。

2

{s2} 查找任何位置包含 200 的任何值。

3

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

4

{s4} 查找以 2 开头且长度至少为 3 个字符的任何值。

5

{s5} 查找以 2 结尾的任何值。

6

{s6} 查找在第二个位置处具有 2 且以 3 结尾的任何值。

7

WHERE SALARY LIKE '2___3' 在以 2 开头、以 3 结尾的五位数中查找任何值。

让我们举一个实际的例子,考虑 CUSTOMER 表,其中记录如下所示。

+----+----------+-----+-----------+----------+
| 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 or ROWNUM Clause

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

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

Syntax

TOP 子句与 SELECT 语句的基本语法如下所示。

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

Example

考虑包含以下记录的 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 Server 上的一个示例,它将从 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 Clause

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

Syntax

ORDER BY 从句的基本语法如下:

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

您可以在 ORDER BY 子句中使用多列。确保用于对该列进行排序的任何列都应位于列列表中。

Example

考虑包含以下记录的 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 子句之前。

Syntax

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

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

Example

考虑 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 Keyword

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

在表中可能存在多个重复记录的情况。在获取此类记录的同时,获取仅那些唯一记录比获取重复记录更有意义。

Syntax

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

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

Example

考虑包含以下记录的 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 |
+----------+

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

SQL> SELECT DISTINCT SALARY FROM CUSTOMERS
   ORDER BY SALARY;

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

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

SQL - SORTING Results

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

Syntax

将用于按升序或降序对结果进行排序的 ORDER BY 子句的基本语法如下:

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

你可以在 ORDER BY 子句中使用多列。确保你用于排序的任何列都应位于列列表中。

Example

考虑包含以下记录的 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 - Constraints

约束是针对表的数据列强制执行的规则。这些规则用于限制可以添加到表中的数据类型。这可确保数据库中的数据准确且可靠。

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

以下是 SQL 中一些最常用的约束。这些约束已经在 SQL - RDBMS Concepts 章节中进行了讨论,但在此时重新审阅它们很有价值。

  1. NOT NULL Constraint − 确保一列不能具有 NULL 值。

  2. UNIQUE Constraint − 确保一列中的所有值都不同。

  3. PRIMARY Key − 唯一标识数据库表中的每行/记录。

  4. FOREIGN Key − 在任何给定的数据库表中唯一标识一行/记录。

  5. INDEX − 用于非常快速地从数据库中创建和提取数据。

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

Dropping Constraints

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

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

ALTER TABLE EMPLOYEES DROP CONSTRAINT EMPLOYEES_PK;

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

ALTER TABLE EMPLOYEES DROP PRIMARY KEY;

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

Integrity Constraints

完整性约束用于确保关系数据库中数据准确且一致。数据完整性通过参照完整性概念在关系数据库中得以处理。

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

SQL - Using Joins

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

考虑以下两张表 −

Table 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 |
+----+----------+-----+-----------+----------+

Table 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 中有不同类型的连接可用 −

  1. INNER JOIN − 当两个表中都匹配时返回行。

  2. LEFT JOIN − 返回左表中的所有行,即使右表中没有匹配项。

  3. RIGHT JOIN − 返回右表中的所有行,即使左表中没有匹配项。

  4. FULL JOIN − 当其中一张表中匹配时返回行。

  5. SELF JOIN − 用于将一张表连接到它自己,就像该表是两张表一样,在 SQL 语句中临时重命名至少一张表。

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

SQL - UNIONS CLAUSE

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

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

  1. 选择了相同数量的列

  2. 相同数量的列表达式

  3. 相同的数据类型且

  4. 具有相同的顺序

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

Syntax

UNION 子句的基本语法如下 −

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

UNION

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

此处,给定的条件可以是基于您的要求的任何给定表达式。

Example

考虑以下两个表。

Table 1 − CUSTOMER 表如下。

+----+----------+-----+-----------+----------+
| 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 |
+----+----------+-----+-----------+----------+

Table 2 − ORDER 表如下。

+-----+---------------------+-------------+--------+
|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                |
+------+----------+--------+---------------------+

The UNION ALL Clause

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

适用于 UNION 子句的相同规则也适用于 UNION ALL 运算符。

Syntax

UNION ALL 的基本语法如下。

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

UNION ALL

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

此处,给定的条件可以是基于您的要求的任何给定表达式。

Example

考虑以下两个表,

Table 1 − CUSTOMER 表如下。

+----+----------+-----+-----------+----------+
| 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 |
+----+----------+-----+-----------+----------+

Table 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 子句。

  1. SQL INTERSECT Clause − 用于合并两个 SELECT 语句,但仅返回与第二个 SELECT 语句中某行相同的第一个 SELECT 语句中的行。

  2. SQL EXCEPT Clause − 这将合并两个 SELECT 语句并返回第一个 SELECT 语句中未由第二个 SELECT 语句返回的行。

SQL - NULL Values

SQL NULL 是用于表示缺失值一词。表中 NULL 值是字段中看似为空的值。

具有 NULL 值的字段是没有任何值的字段。非常重要的一点是要了解 NULL 值不同于零值或包含空格的字段。

Syntax

在创建表时 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 值的字段是在记录创建期间留空的字段。

Example

在选择数据时 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 - Alias Syntax

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

Syntax

table 别名的基本语法如下。

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

column 别名的基本语法如下。

SELECT column_name AS alias_name
FROM table_name
WHERE [condition];

Example

考虑以下两个表。

Table 1 − CUSTOMER 表如下。

+----+----------+-----+-----------+----------+
| 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 |
+----+----------+-----+-----------+----------+

Table 2 − ORDER 表如下。

+-----+---------------------+-------------+--------+
|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 |
+-----+---------------------+-------------+--------+

现在,以下代码块显示了 table alias 的用法。

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 |
+----+----------+-----+--------+

以下是 column alias 的用法。

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 - Indexes

索引是 special lookup tables ,数据库搜索引擎可以使用它来加快数据检索速度。简单地说,索引是一个指向表中数据的指针。数据库中的索引非常类似于书籍后面的索引。

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

索引有助于加快 SELECT 查询和 WHERE 子句的速度,但会使用 UPDATEINSERT 语句减慢数据输入速度。索引可以在不影响数据的情况下创建或删除。

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

索引也可以是唯一的,就像 UNIQUE 约束一样,因为索引可以防止在具有索引的列或列组合中出现重复的条目。

The CREATE INDEX Command

CREATE INDEX 的基本语法如下。

CREATE INDEX index_name ON table_name;

Single-Column Indexes

单列索引只基于一个表列创建。基本语法如下。

CREATE INDEX index_name
ON table_name (column_name);

Unique Indexes

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

CREATE UNIQUE INDEX index_name
on table_name (column_name);

Composite Indexes

复合索引是对表中两列或更多列编制的索引。其基本语法如下。

CREATE INDEX index_name
on table_name (column1, column2);

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

如果只使用了一列,则应该选择单列索引。如果在 WHERE 子句中经常将两列或更多列用作筛选条件,那么复合索引将是最佳选择。

Implicit Indexes

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

The DROP INDEX Command

可以使用 SQL DROP 命令删除索引。删除索引时应小心,因为性能可能会变慢或提升。

基本语法如下 −

DROP INDEX index_name;

可以查看 INDEX Constraint 章节来查看有关索引的一些实际示例。

When should indexes be avoided?

尽管索引旨在增强数据库的性能,但有时应避免使用索引。

以下准则指示应何时重新考虑使用索引。

  1. 不应该在小表中使用索引。

  2. 经常有大量批更新或插入操作的表。

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

  4. 不应该编制经常操作的列的索引。

SQL - ALTER TABLE Command

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

Syntax

在现有表中添加 New Column 的 ALTER TABLE 命令的基本语法如下。

ALTER TABLE table_name ADD column_name datatype;

在现有表中 DROP COLUMN 的 ALTER TABLE 命令的基本语法如下。

ALTER TABLE table_name DROP COLUMN column_name;

更改表中某一列的 DATA TYPE 的 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 的基本语法为 ADD UNIQUE CONSTRAINT 表如下。

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

ALTER TABLE 命令的基本语法为 ADD CHECK CONSTRAINT 表如下。

ALTER TABLE table_name
ADD CONSTRAINT MyUniqueConstraint CHECK (CONDITION);

ALTER TABLE 命令的基本语法为 ADD PRIMARY KEY 表的约束如下。

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

ALTER TABLE 命令的基本语法为 DROP CONSTRAINT 表如下。

ALTER TABLE table_name
DROP CONSTRAINT MyUniqueConstraint;

如果使用的是 MySQL,代码如下 −

ALTER TABLE table_name
DROP INDEX MyUniqueConstraint;

ALTER TABLE 命令的基本语法为 DROP PRIMARY KEY 表的约束如下。

ALTER TABLE table_name
DROP CONSTRAINT MyPrimaryKey;

如果使用的是 MySQL,代码如下 −

ALTER TABLE table_name
DROP PRIMARY KEY;

Example

考虑包含以下记录的 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 |
+----+----------+-----+-----------+----------+

以下是为现有表 ADD New Column 的示例:

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 |
+----+---------+-----+-----------+----------+------+

以下是从现有表中 DROP 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 Command

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

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

Syntax

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

TRUNCATE TABLE  table_name;

Example

考虑具有以下记录的 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 > TRUNCATE TABLE CUSTOMERS;

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

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

SQL - Using Views

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

视图可以包含表的所有行或从表中选择行。视图可以从一张或多张表创建,具体取决于用于创建视图的书面 SQL 查询。

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

  1. 以用户或用户类别觉得自然或直观的方式构建结构化数据。

  2. 限制对数据访问, 以便用户只能看到(有时可以修改)他们需要看到的内容, 不会更多。

  3. 总结可以用来生成报告的不同表中的数据。

Creating Views

使用 CREATE VIEW 语句创建数据库视图。视图可以从单表、多表或其他视图创建。

若要创建视图,用户必须根据具体实现具有适当的系统权限。

基本 CREATE VIEW 语法如下 −

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

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

Example

考虑包含以下记录的 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 |
+----------+-----+

The 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 值的数据定义的。

Updating a View

视图可以在满足以下特定条件下更新:

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

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

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

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

  5. SELECT 子句可能不包含 ORDER BY 子句。

  6. FROM 子句可能不包含多张表。

  7. WHERE 子句可能不包含子查询。

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

  9. 计算后的列可能无法更新。

  10. 基本表中的所有 NOT NULL 列必须包含在视图中,以便 INSERT 查询正常运行。

因此,如果视图满足所有上述规则,您就可以更新该视图。以下代码块演示了更新 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 |
+----+----------+-----+-----------+----------+

Inserting Rows into a View

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

我们无法在 CUSTOMERS_VIEW 中插入行,因为我们没有在此视图中包含所有 NOT NULL 列,否则你可以像在表中那样以类似方式在视图中插入行。

Deleting Rows into a View

可以从视图中删除数据行。适用于 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 |
+----+----------+-----+-----------+----------+

Dropping Views

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

DROP VIEW view_name;

以下是一个从 CUSTOMERS 表中删除 CUSTOMERS_VIEW 的示例。

DROP VIEW CUSTOMERS_VIEW;

SQL - Having Clause

HAVING Clause 允许你指定筛选哪些组结果出现在结果中的条件。

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

Syntax

以下代码块显示 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

Example

可以将 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 - Transactions

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

事务是将一个或多个更改传播到数据库。例如,如果要创建记录或更新记录或从表中删除记录,那么你正在对此表执行事务。控制这些事务以确保数据完整性和处理数据库错误非常重要。

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

Properties of Transactions

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

  1. Atomicity - 确保工作单元中的所有操作都成功完成。否则,事务将在故障点中止,所有先前操作将回滚到其以前的状态。

  2. Consistency - 确保在成功提交事务后数据库正确更改状态。

  3. Isolation - 使事务能够独立于彼此并对彼此透明地操作。

  4. Durability - 确保已提交事务的结果或影响在系统故障的情况下持续存在。

Transaction Control

以下命令用于控制事务。

  1. COMMIT - 保存更改。

  2. ROLLBACK − 回滚更改。

  3. SAVEPOINT − 在事务组中创建回滚点。

  4. SET TRANSACTION − 为事务命名。

Transactional Control Commands

事务控制命令仅与 DML Commands (如 INSERT、UPDATE 和 DELETE)一起使用。在创建或删除表时无法使用它们,因为这些操作会自动在数据库中提交。

The COMMIT Command

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

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

COMMIT 命令的语法如下。

COMMIT;

Example

考虑包含以下记录的 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 |
+----+----------+-----+-----------+----------+

以下是一个示例,它将删除表中 age = 25 的记录,然后 COMMIT 对数据库的更改。

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 |
+----+----------+-----+-----------+----------+

The ROLLBACK Command

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

ROLLBACK 命令的语法如下:

ROLLBACK;

Example

考虑包含以下记录的 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的记录,然后 ROLLBACK 数据库中的更改。

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

因此,delete 操作不会影响该表,并且 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 |
+----+----------+-----+-----------+----------+

The SAVEPOINT Command

SAVEPOINT 是事务中的一个点,当您可以将事务还原到某个点而不还原整个事务时。

SAVEPOINT 命令的语法如下所示。

SAVEPOINT SAVEPOINT_NAME;

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

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

ROLLBACK TO SAVEPOINT_NAME;

以下是一个计划从 CUSTOMERS 表删除三个不同记录的示例。你希望在每次删除前创建一个保存点,以便你能随时回滚到任何保存点,将其相应的数据返回到其初始状态。

Example

可以将 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 的保存点。由于 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.

The RELEASE SAVEPOINT Command

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

RELEASE SAVEPOINT 命令的语法如下。

RELEASE SAVEPOINT SAVEPOINT_NAME;

一旦释放了保存点,就无法再使用 ROLLBACK 命令来撤消自上次保存点执行的事务。

The SET TRANSACTION Command

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

SET TRANSACTION 命令的语法如下。

SET TRANSACTION [ READ WRITE | READ ONLY ];

SQL - Wildcard Operators

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

SQL 支持两个通配符运算符与 LIKE 运算符结合使用,具体说明如下表所示。

Sr.No.

Wildcard & Description

1

The percent sign (%) 匹配一个或多个字符。 Note − MS Access 使用星号 (*) 通配符字符,而不是百分号 (%) 通配符字符。

2

The underscore () 匹配一个字符。 Note − MS Access 使用问号 (?),而不是下划线 () 匹配任何一个字符。

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

Syntax

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

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 可以是任何数字或字符串值。

Example

下表列举了许多示例,展示了包含带有 “%”和 “_”运算符的不同 LIKE 子句的 WHERE 部分。

Sr.No.

Statement & Description

1

{s1} 查找以 200 开头的任何值。

2

{s2} 查找任何位置包含 200 的任何值。

3

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

4

{s4} 查找以 2 开头且长度至少为 3 个字符的任何值。

5

{s5} 查找以 2 结尾的任何值。

6

{s6} 查找在第二个位置处具有 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 表中工资以 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 - Date Functions

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

Sr.No.

Function & Description

1

ADDDATE()Adds dates

2

ADDTIME()Adds time

3

CONVERT_TZ() 从一个时区转换为另一个时区

4

CURDATE()Returns the current date

5

CURRENT_DATE(), CURRENT_DATESynonyms for CURDATE()

6

CURRENT_TIME(), CURRENT_TIMESynonyms for CURTIME()

7

CURRENT_TIMESTAMP(), CURRENT_TIMESTAMPSynonyms for NOW()

8

CURTIME()Returns the current time

9

DATE_ADD()Adds two dates

10

DATE_FORMAT()Formats date as specified

11

DATE_SUB()Subtracts two dates

12

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

13

DATEDIFF()Subtracts two dates

14

DAY()Synonym for DAYOFMONTH()

15

DAYNAME() 返回星期几的名称

16

DAYOFMONTH() 返回一个月中的天数 (1-31)

17

DAYOFWEEK() 返回参数的星期几索引

18

DAYOFYEAR() 返回一年中的天数 (1-366)

19

EXTRACT 提取日期的一部分

20

FROM_DAYS() 将天数转换为日期

21

FROM_UNIXTIME() 将日期格式化为 UNIX 时间戳

22

HOUR()Extracts the hour

23

LAST_DAY 返回参数所属月份的最后一天

24

LOCALTIME(), LOCALTIMESynonym for NOW()

25

LOCALTIMESTAMP, LOCALTIMESTAMP()Synonym for NOW()

26

MAKEDATE() 根据年份和年份中的某一天创建日期

27

MAKETIMEMAKETIME()

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()Returns the second (0-59)

38

STR_TO_DATE() 将字符串转换为日期

39

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

40

SUBTIME()Subtracts times

41

SYSDATE() 返回函数执行时的日期

42

TIME_FORMAT()Formats as time

43

TIME_TO_SEC() 返回转换为秒数的参数

44

TIME() 提取表达式的日期部分

45

TIMEDIFF()Subtracts time

46

TIMESTAMP() 使用单个参数时,此函数将返回日期或 datetime 表达式。使用两个参数时,返回这两个参数的和

47

TIMESTAMPADD() 向 datetime 表达式中添加一个区间

48

TIMESTAMPDIFF() 从 datetime 表达式中减去一个区间

49

TO_DAYS() 返回转换为天数的日期参数

50

UNIX_TIMESTAMP()Returns a UNIX timestamp

51

UTC_DATE() 返回当前 UTC 日期

52

UTC_TIME() 返回当前 UTC 时间

53

UTC_TIMESTAMP() 返回当前 UTC 日期和时间

54

WEEK()Returns the week number

55

WEEKDAY()Returns the weekday index

56

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

57

YEAR()Returns the year

58

YEARWEEK() 返回年份和星期

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

当使用第二个参数的 INTERVAL 形式时,ADDDATE() 是 DATE_ADD() 的同义词。相关函数 SUBDATE() 是 DATE_SUB() 的同义词。有关 INTERVAL 单位参数的信息,请参见 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 是时间或 datetime 表达式,而 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)

此命令将由 from_tz 给出的时区中的 datetime 值 dt 转换为 by 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 and 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 and CURRENT_TIME()

CURRENT_TIME 和 CURRENT_TIME() 与 CURTIME() 同义。

CURRENT_TIMESTAMP and 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 关键字和单位说明符不区分大小写。

下表显示了 expr 参数对于每个单位值的预期形式。

unit Value

Expected exprFormat

MICROSECOND

MICROSECONDS

SECOND

SECONDS

MINUTE

MINUTES

HOUR

HOURS

DAY

DAYS

WEEK

WEEKS

MONTH

MONTHS

QUARTER

QUARTERS

YEAR

YEARS

SECOND_MICROSECOND

'SECONDS.MICROSECONDS'

MINUTE_MICROSECOND

'MINUTES.MICROSECONDS'

MINUTE_SECOND

'MINUTES:SECONDS'

HOUR_MICROSECOND

'HOURS.MICROSECONDS'

HOUR_SECOND

'HOURS:MINUTES:SECONDS'

HOUR_MINUTE

'HOURS:MINUTES'

DAY_MICROSECOND

'DAYS.MICROSECONDS'

DAY_SECOND

'DAYS HOURS:MINUTES:SECONDS'

DAY_MINUTE

'DAYS HOURS:MINUTES'

DAY_HOUR

'DAYS HOURS'

YEAR_MONTH

'YEARS-MONTHS'

MySQL 5.0.0 版本中提供了 QUARTERWEEK 这些值。

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(date,format)

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

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

Sr.No.

Specifier & Description

1

%a Abbreviated weekday name (Sun..Sat)

2

%b Abbreviated month name (Jan..Dec)

3

%c Month, numeric (0..12)

4

%D 月份的日期,带有英文后缀(0th、1st、2nd、3rd、。)

5

%d 月份的日期(00..31)

6

%e 月份的日期(0..31)

7

%f Microseconds (000000..999999)

8

%H Hour (00..23)

9

%h Hour (01..12)

10

%I Hour (01..12)

11

%i Minutes, numeric (00..59)

12

%j Day of year (001..366)

13

%k Hour (0..23)

14

%l Hour (1..12)

15

%M Month name (January..December)

16

%m Month, numeric (00..12)

17

%p AM or PM

18

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

19

%S Seconds (00..59)

20

%s Seconds (00..59)

21

%T Time, 24-hour (hh:mm:ss)

22

%U 第几周(00..53),周日为每周第一天

23

%u 第几周(00..53),周一为每周第一天

24

%V 第几周(01..53),周日为每周第一天;用于 %X

25

%v 第几周(01..53),周一为每周第一天;用于 %x

26

%W Weekday name (Sunday..Saturday)

27

%w 每周中的第几天(0=周日..6=周六)

28

%X 第几周(指定周日为每周第一天),数字形式,四位数;用于 %V

29

%x 第几周(指定周一为每周第一天),数字形式,四位数;用于 %v

30

%Y Year, numeric, four digits

31

%y Year, numeric (two digits)

32

%% A literal .%. character

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(date,INTERVAL expr unit)

这与 DATE_ADD() 函数类似。

DAY(date)

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

DAYNAME(date)

返回指定日期的星期名称。

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

DAYOFMONTH(date)

返回指定日期的当月第几天,范围为 0 至 31。

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

DAYOFWEEK(date)

返回指定日期的星期索引(1 = 周日、2 = 周一、……、7 = 周六)。这些索引值与 ODBC 标准相对应。

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

DAYOFYEAR(date)

返回指定日期的当年的第几天,范围为 1 至 366。

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

EXTRACT(unit FROM date)

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)

Note − 在旧日期中应谨慎使用 FROM_DAYS()。它不适用于格里高利历(1582 年)之前的日期。

FROM_UNIXTIME(unix_timestamp)

FROM_UNIXTIME(unix_timestamp,format)

以“YYYY-MM-DD HH:MM:SS”或“YYYYMMDDHHMMSS”格式,返回 unix_timestamp 参数的表示,具体取决于函数是在字符串中使用还是在数字上下文中使用。该值以当前时区表示。unix_timestamp 参数是内部时间戳值,该值由 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(time)

返回时间的小时。对于当天时间值,返回值范围为 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(date)

接受一个日期或 datetime 值,并返回该月的最后一天的相应值。如果参数无效,则返回 NULL。

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

LOCALTIME and LOCALTIME()

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

LOCALTIMESTAMP and LOCALTIMESTAMP()

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

MAKEDATE(year,dayofyear)

返回一个日期,给定年份和年份内日期的值。年份内日期值必须大于 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(hour,minute,second)

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

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

MICROSECOND(expr)

将时间或 datetime 表达式(expr)中的微秒数作为 0 到 999999 范围内的数字进行返回。

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

MINUTE(time)

返回时间中的分钟,范围为 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(date)

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

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

MONTHNAME(date)

返回日期中月份的全名。

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(date)

返回日期中一年的季度,范围为 1 到 4。

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

SECOND(time)

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

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

SEC_TO_TIME(seconds)

将秒参数转换为小时、分钟和秒,然后以 '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(str,format)

这是 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(date,INTERVAL expr unit) and SUBDATE(expr,days)

当使用第二个参数的 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(expr1,expr2)

SUBTIME() 函数返回 expr1 . expr2,以与 expr1 相同格式的值表示。expr1 值是一个时间或 datetime 表达式,而 expr2 值是一个时间表达式。

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(expr)

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

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(expr1,expr2)

TIMEDIFF()函数返回expr1。expr2表示为时间值。这些expr1和expr2值是时间或日期和时间表达式,但它们都必须是同类型的。

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(expr), TIMESTAMP(expr1,expr2)

对于具有单个参数的函数,则返回日期或日期时间表达式expr作为日期时间值。对于具有两个参数的函数,它会将时间表达式expr2添加到日期或日期时间表达式 expr1 中并将结果作为日期时间值返回。

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

TIMESTAMPADD(unit,interval,datetime_expr)

此函数会将整数表达式interval添加到日期或日期时间表达式 datetime_expr 中。interval的单位由unit参数提供,它应该是以下值之一−

  1. FRAC_SECOND

  2. SECOND, MINUTE

  3. HOUR, DAY

  4. WEEK

  5. MONTH

  6. QUARTER or

  7. YEAR

可以使用显示的一个关键字或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(unit,datetime_expr1,datetime_expr2)

返回日期或日期时间表达式datetime_expr1和datetime_expr2之间的整数差。结果的单位由unit参数给出。unit的合法值与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(time,format)

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

如果时间值包含大于23的小时部分,那么%{s3}和%{s4}小时格式说明符会生成大于通常的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(time)

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

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

TO_DAYS(date)

如果给定日期,则返回一个日号(自0年以来的天数)。

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

UNIX_TIMESTAMP(), UNIX_TIMESTAMP(date)

如果在没有参数的情况下调用此函数,则它会以无符号整数的形式返回一个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()

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

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()

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

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()

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

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(date[,mode])

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

Mode

First Day of week

Range

星期1是第一周。

0

Sunday

0-53

今年的星期日

1

Monday

0-53

今年超过 3 天

2

Sunday

1-53

今年的星期日

3

Monday

1-53

今年超过 3 天

4

Sunday

0-53

今年超过 3 天

5

Monday

0-53

今年的星期一

6

Sunday

1-53

今年超过 3 天

7

Monday

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,或者 .zero.date 的 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)

Note - 对于可选参数 0 或 1(那时 WEEK() 会返回给定年份中的一周),周数不同于 WEEK() 函数返回的周数 (0)。

SQL - Temporary Tables

What are Temporary Tables?

有些 RDBMS 支持临时表。临时表是一项极好的功能,使您可以 store and process intermediate results 使用与在典型 SQL Server 表中可以使用相同的筛选、更新与联接功能。

在某些情况下,临时表可能对保存临时数据非常有用。应该了解关于临时表的最重要的事情是,在当前客户端会话终止时,这些表将被删除。

MySQL 3.23 及更高版本中提供了临时表。如果您使用的是比 3.23 更旧版本的 MySQL,那么您不能使用临时表,但可以使用 heap tables

如前所述,临时表只会持续到会话结束为止。如果您在 PHP 脚本中运行代码,那么临时表将在脚本执行完毕后自动销毁。如果您通过 MySQL 客户端程序连接到 MySQL 数据库服务器,那么该临时表将一直存在到您关闭客户端或手动销毁表为止。

Example

以下示例展示了临时表的使用方法。

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 命令,那么您将发现数据库中没有可用数据。您的临时表甚至都不会存在。

Dropping Temporary Tables

默认情况下,数据库连接终止时,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 - Clone Tables

有时您可能需要一个精确的数据表副本,而 CREATE TABLE …​ 或 SELECT…​ 命令无法达到您的目的,因为副本必须包含相同的索引、默认值等等。

如果您使用的是 MySQL RDBMS,那么您可以按照下列步骤来处理这种情况:

  1. 使用 SHOW CREATE TABLE 命令来获取一个 CREATE TABLE 语句,该语句指定源数据表的结构、索引等信息。

  2. 将语句修改为将表名称修改为克隆表的表名称,并执行该语句。这样您就拥有了一个精确的克隆表。

  3. 可选地,如果您还需要复制表内容,也请发出 INSERT INTO 或 SELECT 语句。

Example

尝试使用以下示例为 TUTORIALS_TBL 创建一个克隆表,其结构如下 −

Step 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)

Step 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)

Step 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 - Sub Queries

一个子查询或内部查询或一个嵌套查询是在另一个 SQL 查询中的查询,并且嵌入在 WHERE 子句中。

一个子查询用于返回在主查询中的某个条件中将被用于进一步限制要检索的数据的数据。

子查询可以与 SELECT、INSERT、UPDATE 和 DELETE 语句一起使用,以及 =、<、>、>=、⇐、IN、BETWEEN 等运算符一起使用。

有一些规则,子查询必须遵守 −

  1. 子查询必须用括号括起来。

  2. 子查询的 SELECT 子句中只能有一列,除非主查询中的多列是供子查询比较其所选列用的。

  3. 虽然主查询可以使用 ORDER BY,但在子查询中却不能使用 ORDER BY 命令。GROUP BY 命令可以用来执行与 ORDER BY 在子查询中相同的函数。

  4. 仅当与多值运算符(如 IN 运算符)一起使用时,才能使用返回多行的数据的子查询。

  5. SELECT 列表中不能包含引用计算为 BLOB、ARRAY、CLOB 或 NCLOB 的值。

  6. 子查询不能立即包含在某个集合函数中。

  7. BETWEEN 运算符不能与子查询一起使用。但是,BETWEEN 运算符可以在子查询中使用。

Subqueries with the SELECT Statement

子查询最常与SELECT语句一起使用。基本语法如下所示:

SELECT column_name [, column_name ]
FROM   table1 [, table2 ]
WHERE  column_name OPERATOR
   (SELECT column_name [, column_name ]
   FROM table1 [, table2 ]
   [WHERE])

Example

考虑包含以下记录的 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 |
+----+----------+-----+---------+----------+

Subqueries with the INSERT Statement

子查询也可以与 INSERT 语句一起使用。INSERT 语句使用从子查询返回的数据插入另一张表中。子查询中的所选数据可以使用任何字符、时间或数字函数来修改。

基本语法如下。

INSERT INTO table_name [ (column1 [, column2 ]) ]
   SELECT [ *|column1 [, column2 ]
   FROM table1 [, table2 ]
   [ WHERE VALUE OPERATOR ]

Example

考虑一张 CUSTOMERS_BKP 表,其结构与 CUSTOMERS 表相似。现在要将完整的 CUSTOMERS 表复制到 CUSTOMERS_BKP 表,您可以使用以下语法。

SQL> INSERT INTO CUSTOMERS_BKP
   SELECT * FROM CUSTOMERS
   WHERE ID IN (SELECT ID
   FROM CUSTOMERS) ;

Subqueries with the UPDATE Statement

子查询可以与 UPDATE 语句联合使用。在使用 UPDATE 语句与子查询时,可以更新表中的单个或多个列。

基本语法如下。

UPDATE table
SET column_name = new_value
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

Example

假设我们有一个可用的 CUSTOMERS_BKP 表,该表是 CUSTOMERS 表的备份。以下示例为 CUSTOMERS 表中 AGE 大于或等于 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 |
+----+----------+-----+-----------+----------+

Subqueries with the DELETE Statement

与上面提到的其他任何语句一样,子查询可与 DELETE 语句一起使用。

基本语法如下。

DELETE FROM TABLE_NAME
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

Example

假设我们有一个可用的 CUSTOMERS_BKP 表,该表是 CUSTOMERS 表的备份。以下示例会删除 CUSTOMERS 表中 AGE 大于或等于 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 - Using Sequences

序列是一组按顺序生成的整数 1、2、3、……​。序列经常在数据库中使用,因为许多应用程序要求表中的每行都包含一个唯一的值,而序列提供了一种简单的方法来生成这些值。

本章介绍如何在 MySQL 中使用序列。

Using AUTO_INCREMENT column

在 MySQL 中使用序列的最简单方法是将列定义为 AUTO_INCREMENT,其余部分让 MySQL 处理。

Example

试用以下示例。这将创建一个表,然后在该表中插入几行,其中不需要提供记录 ID,因为 MySQL 会自动增量这个 ID。

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)

Obtain AUTO_INCREMENT Values

LAST_INSERT_ID( ) 是一个 SQL 函数,因此你可以从任何了解如何发出 SQL 语句的客户端中使用它。否则,PERL 和 PHP 脚本会提供专属函数来检索最后一条记录的自动增量值。

PERL Example

使用 mysql_insertid 属性获取查询生成的 AUTO_INCREMENT 值。此属性可通过数据库句柄或语句句柄进行访问,具体取决于你如何发出查询。以下示例通过数据库句柄对此进行引用。

$dbh->do ("INSERT INTO INSECT (name,date,origin)
VALUES('moth','2001-09-14','windowsill')");
my $seq = $dbh->{mysql_insertid};

PHP Example

在发出生成 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);

Renumbering an Existing Sequence

在某些情况下,你可能从表中删除了许多记录,并且希望对所有记录重新排序。这可以使用一个简单的技巧来实现,但你应该非常小心地执行此操作,并检查你的表是否与另一个表有联接。

如果你确定对 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);

Starting a Sequence at a Particular Value

默认情况下,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 - Handling Duplicates

在表中,你可能会遇到重复记录的情况。在获取这些记录时,只获取唯一记录比获取重复记录更有意义。

我们已经讨论过的 SQL DISTINCT 关键字,它与 SELECT 语句结合使用,可以消除所有重复记录,只获取唯一记录。

Syntax

消除重复记录的 DISTINCT 关键字的基本语法如下。

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

Example

可以将 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 - Injection

如果你通过网页获取用户输入并将其插入 SQL 数据库,那么你很可能会让自己处于一种称为 SQL Injection 的安全问题之中。本章将教你如何帮助防止这种情况的发生以及帮助你在服务器端脚本(例如 PERL 脚本)中保护脚本和 SQL 语句。

通常当您要求用户输入姓名时,会出现注入,而用户不提供姓名,而是提供将在数据库中不知不觉运行的 SQL 语句。切勿信任用户提供的数据,只有在验证后才处理此数据;根据规则,这可以通过 Pattern Matching 完成。

在下例中, 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 仅包含字母数字字符,或许还有空格,例如字符串 ilia。但是在这里,通过将一个全新的查询附加到 $name,对数据库的调用变成了灾难;注入的 DELETE 查询从 CUSTOMERS 表中删除了所有记录。

幸运的是,如果你使用 MySQL, mysql_query() 函数不允许在单个函数调用中查询堆栈或执行多个 SQL 查询。如果你尝试堆叠查询,调用将失败。

但是,其他 PHP 数据库扩展,例如 SQLitePostgreSQL 会愉快地执行堆积的查询,执行在一个字符串中提供的查询并创建严重的安全问题。

Preventing SQL Injection

您可以在 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}'");

The LIKE Quandary

为了解决 LIKE 难题,自定义转义机制必须将用户提供的 '%' 和 '_' 字符转换为文本。使用 addcslashes() ,此函数允许您指定要转义的字符范围。

$sub = addcslashes(mysql_real_escape_string("%str"), "%_");
// $sub == \%str\_
mysql_query("SELECT * FROM messages
   WHERE subject LIKE '{$sub}%'");

SQL - Database Tunning

成为一名数据库专家或专家数据库管理员需要时间。所有这些都伴随着各种数据库设计和良好的培训的丰富经验。

但以下列表可能有助于初学者以出色的方式应用数据库 -

  1. 使用本教程在 RDBMS 概念章节中解释的 3BNF 数据库设计。

  2. 避免数字到字符的转换,因为数字和字符的比较方式不同,并且会导致性能下降。

  3. 在使用 SELECT 语句时,只获取所需的信息,避免在 SELECT 查询中使用 *,因为它会不必要地加载系统。

  4. 在所有有频繁搜索操作的表上小心创建索引。避免在搜索操作较少、插入和更新操作较多的表上创建索引。

  5. 当 WHERE 子句中的列没有与之关联的索引时,就会发生全表扫描。你可以通过在 SQL 语句的 WHERE 子句中用作条件的列上创建索引来避免全表扫描。

  6. 非常小心涉及实数和日期/时间值的相等运算符。这两者都会有一些肉眼不可见的细微差别,导致精确匹配是不可能的,从而阻止你的查询返回行。

  7. 谨慎地使用模式匹配。LIKE COL% 是一个有效的 WHERE 条件,它将返回的集合减少到仅包含以字符串 COL 开头的数据的记录。但是,COL%Y 不会进一步减少返回的结果集,因为无法有效地评估 %Y。进行评估的努力太大,无法考虑。在这种情况下,使用了 COL%,但 %Y 被丢弃了。出于同样的原因,前导通配符 %COL 有效地阻止了整个筛选器被使用。

  8. 精细调整 SQL 查询,检查查询的结构(及子查询),SQL 语法,以发现是否设计了自己的表来支持快速的数据处理,并且以最佳方式编写了查询,从而允许 DBMS 有效地处理数据。

  9. 对于定期执行的查询,尽可能使用存储过程。存储过程是可能包含大量 SQL 语句的一组查询。存储过程由数据库引擎编译,然后执行。与 SQL 语句不同的是,数据库引擎不必在执行存储过程之前优化该过程。

  10. 尽可能避免在查询中使用逻辑运算符 OR。对于大小较大的表,OR 会不可避免地减慢几乎任何查询。

  11. 你可以通过放弃索引来优化批量数据加载。想象一下有成千上万行的历史表。那个历史表也可能有一个或多个索引。当想到索引时,通常会想到可以加快表访问,但在批量加载的情况下,放弃索引(es)会从中受益。

  12. 在执行批处理事务时,在相当多的记录创建完成后执行 COMMIT,而不是在每次创建记录后创建。

  13. 规划定期对数据库进行碎片整理,即使这意味着开发周例程。

Built-In Tuning Tools

Oracle 有许多用于管理 SQL 语句性能的工具,但其中两个非常流行。这两个工具是:

  1. Explain plan - 工具识别在执行 SQL 语句时要采用的访问路径。

  2. tkprof - 通过衡量 SQL 语句处理的每个阶段所用时间来衡量性能。

如果只想衡量 Oracle 中查询的耗时,可以使用 SQL*Plus 命令 SET TIMING ON。

查看 RDBMS 文档,了解上述工具和数据库碎片整理的更多详细信息。