SQL - 限制和排序数据



SELECT 语句的基本功能包括选择、投影和连接。从表中显示特定列称为投影操作。我们现在将重点放在显示特定的输出行。这称为选择操作。可以通过在 SELECT 查询中添加 WHERE 子句来选择特定的行。事实上,WHERE 子句出现在 SELECT 查询层次结构中的 FROM 子句之后。在所有情况下都必须保持此顺序。如果违反,Oracle 会引发异常。

语法

SELECT *|{[DISTINCT] column| expression [alias],..}
FROM table
[WHERE condition(s)]

在语法中,

  • WHERE 子句是关键字

  • [condition] 包含列名、表达式、常量、字面量和比较运算符。

假设您的经理正在处理组织的季度预算。作为此活动的一部分,需要生成每个员工基本详细信息的列表,但仅限于年薪至少 25,000 美元的员工。下面的 SQL 查询完成了此任务。请注意粗体显示的 WHERE 子句的使用。

SELECT Employee_ID, Last_Name, First_Name, Salary
FROM employees
WHERE Salary >= 25000;  

EMPLOYEE_ID  LAST_NAME        FIRST_NAME       SALARY
----------   ---------------  ---------------  -----------
88303        Jones            Quincey          $30,550.00
88404        Barlow           William          $27,500.00
88505        Smith            Susan            $32,500.00

3 rows selected 

需要注意的要点 -

  • 一个 SELECT 子句只能包含一个 WHERE 子句。但是,可以使用 AND 或 OR 运算符将多个过滤条件附加到 WHERE 子句。

  • 谓词子句中的列、字面量或表达式必须具有相似或可相互转换的数据类型。

  • WHERE 子句中不能使用列别名。

  • 字符字面量必须用单引号括起来,并且区分大小写。

  • 日期字面量必须用单引号括起来,并且对格式敏感。默认格式为DD-MON-RR

比较运算符

比较运算符用于谓词中,将一个项或操作数与另一个项进行比较。SQL 提供了全面的相等、不等和杂项运算符集。它们可以根据 SELECT 查询中的数据和过滤条件逻辑使用。当您在 WHERE 子句中使用比较运算符时,运算符两侧的参数(您要比较的对象或值)必须是列名或特定值。如果使用特定值,则该值必须是数字值或字面字符串。如果该值是字符字符串或日期,则必须在单引号 (' ') 内输入该值。

Oracle 有九个比较运算符可用于相等或不等条件。

Operator  Meaning
=         equal to 
<         less than
>         greater than
>=        greater than or equal to
<=        less than or equal to
!=        not equal to
<>        not equal to 

其他 Oracle 运算符包括 BETWEEN..AND、IN、LIKE 和 IS NULL。

BETWEEN 运算符

BETWEEN 运算符可用于比较一定范围内列的值。指定的范围必须具有下限和上限,在比较期间两者都包含在内。其用法类似于复合不等式运算符(<= 和 >=)。它可以用于数字、字符和日期类型值。

例如,SELECT 查询中的 WHERE 条件SALARY BETWEEN 1500 AND 2500 将列出薪资在 1500 到 2500 之间的员工。

IN 运算符

IN 运算符用于测试给定值集中列的值。如果列可以与给定集中任何值相等,则验证条件。使用 IN 运算符定义的条件也称为成员资格条件。

例如,SELECT 查询中的 WHERE 条件SALARY IN (1500, 3000, 2500) 将限制薪资为 1500、3000 或 2500 的行。

LIKE 运算符

LIKE 运算符用于在 SELECT 查询中进行模式匹配和通配符搜索。如果列值的某一部分未知,则可以使用通配符来替换未知部分。它使用通配符运算符构建搜索字符串,因此搜索称为通配符搜索。这两个运算符是百分号 ('%') 和下划线 ('_')。下划线 ('_') 替换单个字符,而百分号 ('%') 替换多个字符。它们也可以组合使用。

例如,下面的 SELECT 查询列出姓氏以 'SA' 开头的员工的姓氏。

SELECT first_name
FROM employees
WHERE last_name LIKE 'SA%';

IS (NOT) NULL 条件

需要注意的是,不能使用等号运算符测试 NULL 值。这是因为 NULL 值是未知的和未分配的,而等号运算符测试的是确定值。IS NULL 运算符充当等号运算符,用于检查列的 NULL 值。

例如,SELECT 查询中的 WHERE 条件COMMISSION_PCT IS NULL 将列出没有佣金百分比的员工。

逻辑运算符

可以将多个过滤条件添加到 WHERE 子句谓词。可以使用逻辑运算符 AND、OR 和 NOT 将多个条件组合在一起。

  • AND:连接两个或多个条件,并且仅当所有条件都为真时才返回结果。

  • OR:连接两个或多个条件,并且当任何条件为真时都返回结果。

  • NOT:否定其后的表达式。

AND 运算符链接 WHERE 子句中的两个或多个条件,并且仅当所有条件都为真时才返回 TRUE。假设经理需要一份女性员工的名单。此外,该列表应仅包含姓氏以字母“E”开头或在字母表中排在后面的员工。此外,结果表应按员工姓氏排序。有两个简单的条件需要满足。WHERE 子句可以写成:WHERE Gender = 'F' AND last_name > 'E'。

SELECT last_name "Last Name", first_name "First Name", Gender "Gender"
FROM employees
WHERE Gender = 'F' AND last_name > 'E'
ORDER BY last_name;

OR 运算符链接 WHERE 子句中的多个条件,并且如果任一条件返回 true,则返回 TRUE。假设您组织经理的要求略有变化。需要另一个员工列表,但在此列表中,员工应:(1)是女性,或(2)姓氏以字母“T”开头或字母表中排在后面的字母。结果表应按员工姓氏排序。在这种情况下,可以满足两个条件中的任何一个以满足查询。应列出女性员工以及满足第二个条件的员工。

NOT 运算符用于否定表达式或条件。

ORDER BY 子句

当您仅显示几行数据时,可能不需要对输出进行排序;但是,当您显示多行时,通过对信息进行排序可以帮助经理做出决策。可以使用可选的 ORDER BY 子句对 SELECT 语句的输出进行排序。当您使用 ORDER BY 子句时,您要排序的列名也必须是 SELECT 子句中指定的列名。

下面的 SQL 查询使用 ORDER BY 子句按升序对结果表中的 last_name 列进行排序。升序是默认排序顺序。

SELECT last_name, first_name
FROM employees
WHERE last_name >= 'J'
ORDER BY last_name;

last_name        first_name
---------------  ---------------
Jones            Quincey
Klepper          Robert
Quattromani      Toni
Schultheis       Robert

排序也可以基于数字和日期值。也可以基于多列进行排序。

默认情况下,ORDER BY 子句将按升序对结果表中的输出行进行排序。我们可以使用关键字 DESC(代表降序)启用降序排序。另一种默认值是 ASC,它按升序排序,但 ASC 关键字很少使用,因为它已成为默认值。当使用 ASC 或 DESC 可选关键字时,它必须跟随您在 WHERE 子句中排序的列名。

位置排序 - 可以ORDER BY 子句中使用选定列列表中列的数字位置,而不是列名。它主要用于 UNION 查询(稍后讨论)。该查询按 salary 对结果集进行排序,因为它在列列表中排在第 2 位。

SELECT  first_name, salary
FROM employees
ORDER BY 2;

替换变量

当 SQL 查询必须针对不同的输入集执行多次时,可以使用替换变量。可以在查询执行之前使用替换变量提示用户输入。它们广泛用于基于查询的报表生成,该报表从用户处获取数据范围作为条件过滤和数据显示的输入。替换变量以单个&符号开头,用于临时存储值。例如,

SELECT EMPLOYEE_ID, LAST_NAME, SALARY
FROM employees
WHERE LAST_NAME = &last_name
OR EMPLOYEE_ID = &EMPNO;

当执行上述 SELECT 查询时,Oracle 将“&”识别为替换变量。它提示用户如下输入“last_name”和“EMPNO”的值。

Enter value for last_name:
Enter value for empno:

一旦用户为这两个变量提供输入,就会替换值,验证并执行查询。

需要注意的要点 -

  • 如果变量旨在替换字符或日期值,则需要将字面量用单引号括起来。在处理字符和日期值时,将&替换变量用单引号括起来是一个有用的技巧。

  • SQL Developer 和 SQL*Plus 都支持替换变量和 DEFINE/UNDEFINE 命令。尽管 SQL Developer 或 SQL*Plus 不支持对用户输入进行验证检查(数据类型除外)。

  • 您不仅可以在 SQL 语句的 WHERE 子句中使用替换变量,还可以将其用作列名、表达式或文本的替换。

使用双&替换变量

当在多个地方使用相同的替换变量时,为了避免再次重新输入相同的数据,我们使用双&替换。在这种情况下,一旦输入替换变量的值,就会在所有使用位置进行替换。

SELECT first_name, HIRE_DATE, SEPARATION_DATE
FROM employees
WHERE HIRE_DATE LIKE '%&DT%' AND SEPARATION_DATE '%&&DT%'

请注意,在上述查询中,&DT 的值被替换了两次。因此,用户一旦提供其值,它将在两个位置被替换。

DEFINE 和 VERIFY 命令

在 SQL*Plus 中,使用 DEFINE 功能设置会话中变量的定义。变量可以在会话中定义,从而避免查询执行期间停止。Oracle 在 SQL 查询中遇到相同的变量时会读取它。默认情况下处于开启状态。借助 DEFINE 子句,可以在查询执行之前在命令行中声明变量,例如 **DEFINE variable=value;**。

Verify 命令验证上述替换,显示为 OLD 和 NEW 语句。默认情况下处于关闭状态,可以使用 SET 命令将其设置为开启状态。

SQL> SET DEFINE ON
SQL> SET VERIFY ON
SQL> DEFINE NAME = MARTIN'
SQL> SELECT first_name, SALARY 
FROM employees
WHERE first_name = '&NAME';
OLD   1: select first_name, sal from employee where first_name = '&first_name'
new   1: select first_name, sal from employee where first_name = 'MARTIN'

first_name     SALARY
-------        -------
MARTIN         5000
广告