欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SQL从入门到出门 第3篇 初级查询

程序员文章站 2024-01-15 20:03:40
...

本篇介绍SQL:2016(ISO/IEC 9075:2016)标准中定义的查询语句,以及六种主流数据库中的实现及差异:Oracle、MySQL、Microsoft SQL Server、PostgreSQL、Db2、SQLite。

从本篇开始,我们使用的示例数据库结构如下图所示。
SQL从入门到出门 第3篇 初级查询
其中包含7个表和1个视图。

  • regions,全球区域表
  • countries,国家信息表,通过region_id关联regions表
  • locations,街道地址表,通过country_id关联countries表
  • departments,部门信息表,通过location_id关联locations表,通过manager_id关联employees表
  • employees,员工信息表,通过department_id关联departments表,通过job_id关联jobs表,通过manager_id与自己关联
  • jobs,职位信息表
  • job_history,员工任职历史表,通过employee_id关联employees表,通过department_id关联departments表,通过job_id关联jobs表
  • emp_details_view,员工详细信息视图,同时显示了多个表中的关联信息

创建示例数据库的SQLite脚本点击下载

不同的数据库产品都提供了自己的管理和开发工具,例如MySQL的MySQL Workbench,Oracle的SQL Developer。本文推荐一个第三方的免费工具:DBeaver,它可以通过JDBC连接几乎所有的数据库。

先从最简单的查询开始,SQL中的查询使用SELECT语句表示。

最简单的查询

一个最简单的查询示例如下:

SELECT first_name,
       last_name
  FROM employees;

其中SELECTFROM称为关键字,它们不区分大小写,建议大写,便于阅读。

SELECT表示一条查询语句,后面是要显示的信息,使用逗号分隔;FROM表示要从哪个表中进行查询;分号表示语句结束。

更一般的查询语法如下:

SELECT column1, column2, ... 
  FROM table;

以上示例查询的结果如下(共计107条):
SQL从入门到出门 第3篇 初级查询

如果表中的列较多,为了快速查看所有列的信息,可以使用星号(*)表示。

SELECT * 
  FROM employees;

以上查询将会显示employees表的所有列。
SQL从入门到出门 第3篇 初级查询

在实际项目中,不要使用 SELECT *,避免表结构变更带来的不确定性。

除此之外,许多数据库还支持另一种更简单的查询:

SELECT 1+1;

这种形式不属于SQL标准规范,它不需要FROM关键字,可以用于快速查询信息,或者当作计算器使用。

数据库 不带FROM的SELECT 描述
Oracle N/A                               Oracle提供了一个单行单列的dual表,用于执行这种简单的查询和计算:
SELECT 1+1 FROM dual;
MySQL OK MySQL也提供了dual表
SQL Server OK
PostgreSQL OK
Db2 N/A Db2也提供了Oracle中类似的表:
SELECT 1+1 FROM sysibm.sysdummy1;
SQLite OK

消除重复值

在SQL中,提供了DISTINCT关键字,用于删除查询结果中的重复值。例如:

SELECT DISTINCT
       first_name
  FROM employees;

DISTINCT位于SELECT之后,可以基于多个列值进行查重操作,通用语法如下:

SELECT DISTINCT
       column1,
       column2,
       ...
  FROM table;

为了消除重复值,数据库系统需要对结果进行排序,然后扫描重复值;因此,大量数据的重复值处理会降低查询的速度。

以上示例的结果如下(共计91条):
SQL从入门到出门 第3篇 初级查询
查询结果只有91条,而不是107条,这是因为 first_name 中有重复的数据。

DISTINCT对于多个NULL值,只会返回1条空值记录。例如:

SELECT DISTINCT
       commission_pct
  FROM employees;

除了DISTINCT之外,另一个关键字是ALL,它不会排除重复的结果,而是显示所有数据:

SELECT [ALL | DISTINCT]
       column1,
       column2,
       ...
  FROM table;

如果不指定,默认值为ALL

数据库 SELECT [ALL | DISTINCT] 描述
Oracle OK Oracle 还支持UNIQUE关键字,等价于DISTINCT
MySQL OK MySQL 还支持DISTINCTROW关键字,等价于DISTINCT
SQL Server OK
PostgreSQL OK PostgreSQL 还支持使用DISTINCT ON指定基于哪些列进行重复值检测
Db2 OK Db2 还支持UNIQUE关键字,等价于DISTINCT
SQLite OK
                                                      

使用列别名

在查询结果中,可以通过使用列别名为列指定一个临时的名称,以提高可读性。

SELECT c1 AS column_alias1,
       c2 column_alias2,
  FROM table;

关键字AS用于定义一个别名,也可以省略,只保留一个空格。

SELECT commission_pct AS 'Commission percentage' 
  FROM employees;

当列别名中包含空格或者特殊字符时,需要将别名引用起来,不同的数据库产品使用不同的引用符号。

数据库 使用列别名 描述
Oracle OK                       Oracle返回大写的列名,对于包含空格的列别名使用双引号进行引用
MySQL OK MySQL对于包含空格的列别名支持单引号或者双引号或者反单引号(`)引用
SQL Server OK SQL Server对于包含空格的列别名支持单引号或者双引号或者中括号([ ])引用
PostgreSQL OK PostgreSQL返回小写的列名,对于包含空格的列别名使用双引号进行引用
Db2 OK 返回大写的列名,对于包含空格的列别名使用双引号进行引用
SQLite OK SQLite对于包含空格的列别名支持以上各种符号引用

除了列别名之外,SQL还支持表别名,我们将在介绍多表连接查询(JOIN)时解释表的别名。

SQL中的注释

在SQL中,可以像其他编程语言一样使用注释,注释不会被执行。

SQL中的注释分为单行注释和多行注释。

单行注释以两个连字符(–)开始,直到这一行结束。例如:

SELECT DISTINCT
       first_name   -- distinct will remove duplicate records
  FROM employees;

多行注释使用C语言风格的注释方法(/* … */)。例如:

SELECT DISTINCT
       first_name 
       /*  distinct will remove 
           duplicate records from results
       */
  FROM employees;

除了SQL标准中的两种注释方式之外,不同数据库还提供了额外的扩展。

数据库 SQL中的注释 描述
Oracle OK                       Oracle中的特殊用法 –+ 和 /*+ hint */ 用于表示查询提示,参考Oracle文档
MySQL OK MySQL中的 # 也可以用单行注释;/*+ hint */ 用于优化器提示;/*! */ 也属于特殊用法
SQL Server OK
PostgreSQL OK
Db2 OK
SQLite OK
相关标签: SQL 查询语句