oracle

关注公众号 jb51net

关闭
首页 > 数据库 > oracle > Oracle单表查询

Oracle数据库查询之单表查询的关键子句及其用法

作者:IvanCodes

在Oracle数据库管理中了解如何查询表的最近更改数据对于跟踪和审计数据库的变化至关重要,这篇文章主要介绍了Oracle数据库查询之单表查询的关键子句及其用法,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

在 Oracle 数据库操作中,查询数据是最频繁、最核心的操作之一。单表查询,即仅从一个表中检索信息,是所有复杂查询的基础。本笔记将系统梳理单表查询的关键子句及其用法,并特别介绍Oracle中伪列的使用。

思维导图

一、SELECT 语句基本结构

一个完整的单表查询语句通常包含以下按执行顺序排列 (逻辑上) 的子句:

SELECT <select_list>                -- 5. 选择要显示的列或表达式
FROM <table_name>                  -- 1. 指定数据来源表
[WHERE <filter_conditions>]        -- 2. 行过滤条件
[GROUP BY <group_by_expression>]   -- 3. 分组依据
[HAVING <group_filter_conditions>] -- 4. 分组后的过滤条件
[ORDER BY <order_by_expression>];  -- 6. 结果排序

二、SELECT 子句:选择列与表达式

SELECT * FROM employees;
SELECT employee_id, first_name, salary FROM employees;
SELECT employee_id AS "员工编号", first_name "名", salary "月薪" FROM employees;
SELECT salary * 12 AS annual_salary FROM employees;
SELECT last_name || ', ' || first_name AS full_name, salary / 30 AS daily_rate FROM employees;
SELECT SYSDATE - hire_date AS days_employed FROM employees;
SELECT UPPER(first_name) AS upper_first_name FROM employees;
SELECT DISTINCT department_id FROM employees;
SELECT DISTINCT department_id, job_id FROM employees;
SELECT first_name, salary, 'Oracle Corp' AS company_name FROM employees;

三、FROM 子句:指定表

对于单表查询,FROM 子句非常简单,就是指定要查询的那个表名。

FROM employees;

可以为表指定别名,在单表查询中不常用,但在多表连接或子查询中非常有用。

FROM employees e;

四、WHERE 子句:行过滤

WHERE 子句用于根据指定的条件筛选出满足要求的行。

常用比较运算符:= (等于), > (大于), < (小于), >= (大于等于), <= (小于等于), <> 或 != (不等于)。

逻辑运算符:AND (与), OR (或), NOT (非)。

其他常用条件:

SELECT first_name, salary FROM employees WHERE salary BETWEEN 5000 AND 10000;
SELECT first_name, department_id FROM employees WHERE department_id IN (10, 20, 30);
SELECT first_name FROM employees WHERE first_name LIKE 'A%';
SELECT last_name FROM employees WHERE last_name LIKE '_o%';
SELECT note FROM notes WHERE note LIKE '100\%%' ESCAPE '\';
SELECT first_name, commission_pct FROM employees WHERE commission_pct IS NULL;

代码案例:查询薪水大于8000且部门ID为90的员工:

SELECT employee_id, first_name, salary, department_id
FROM employees
WHERE salary > 8000 AND department_id = 90;

查询部门ID为10或20,或者职位ID以 ‘SA_’ 开头的员工:

SELECT employee_id, department_id, job_id
FROM employees
WHERE department_id IN (10, 20) OR job_id LIKE 'SA\_%';

五、Oracle 伪列 (Pseudocolumns)

Oracle 提供了一些特殊的列,它们不实际存储在表中,但可以像普通列一样在SQL语句中引用。这些被称为伪列。

常用的伪列:

SELECT ROWID, employee_id, first_name FROM employees WHERE ROWNUM &lt;= 5;
-- 获取前5名员工 (基于默认顺序或ORDER BY之前的顺序)
SELECT employee_id, first_name, salary FROM employees WHERE ROWNUM <= 5;

-- 错误的方式尝试获取第6到第10名员工
-- SELECT * FROM employees WHERE ROWNUM > 5 AND ROWNUM <= 10; (通常不会返回任何结果)

-- 正确的分页方式 (使用子查询)
SELECT *
FROM (SELECT employee_id, first_name, salary, ROWNUM AS rn
      FROM (SELECT employee_id, first_name, salary
            FROM employees
            ORDER BY salary DESC)) -- 内层先排序
WHERE rn BETWEEN 6 AND 10;
-- 假设employees表有 manager_id 列,形成层级关系
SELECT LEVEL, employee_id, first_name, manager_id
FROM employees
START WITH manager_id IS NULL -- 定义根节点
CONNECT BY PRIOR employee_id = manager_id; -- 定义父子关系
-- 假设存在一个名为 employee_seq 的序列
CREATE SEQUENCE employee_seq START WITH 200 INCREMENT BY 1;

INSERT INTO employees (employee_id, first_name, last_name, email)
VALUES (employee_seq.NEXTVAL, 'New', 'Employee', 'new.emp@example.com');

SELECT employee_seq.CURRVAL FROM dual; -- 查看当前会话中序列的当前值

六、GROUP BY 子句:数据分组

GROUP BY 子句将具有相同值的行组织成一个摘要组。通常与聚合函数 (如 COUNT()SUM()AVG()MAX()MIN()) 一起使用,对每个组进行计算。

聚合函数: (与之前版本相同)

使用规则:

代码案例:查询每个部门的员工人数:

SELECT department_id, COUNT(*) AS num_employees
FROM employees
GROUP BY department_id;

七、HAVING 子句:分组过滤

HAVING 子句用于在数据分组后对分组结果进行进一步筛选。它通常包含聚合函数。

代码案例:查询平均薪水大于8000的部门:

SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
HAVING AVG(salary) > 8000;

八、ORDER BY 子句:结果排序

ORDER BY 子句用于对最终查询结果集进行排序。它是查询语句中逻辑上最后执行的部分。

排序方式: (与之前版本相同)

代码案例:按薪水降序排列员工信息:

SELECT employee_id, first_name, salary
FROM employees
ORDER BY salary DESC;

总结: 单表查询是 Oracle SQL 的基石。熟练掌握各子句的功能、用法、执行顺序,以及伪列 (特别是 ROWNUM 和 ROWID) 的特性,是编写高效、准确查询的关键。

练习题

背景表:假设我们有一个 products 表,结构如下:

CREATE TABLE products (
product_id NUMBER PRIMARY KEY,
product_name VARCHAR2(100) NOT NULL,
category_id NUMBER,
supplier_id NUMBER,
unit_price NUMBER(10,2),
units_in_stock NUMBER,
discontinued CHAR(1) DEFAULT 'N' -- 'Y' or 'N'
);
-- 插入一些样例数据 (请自行补充更多数据以测试所有题目)
INSERT INTO products VALUES (1, 'Chai', 10, 1, 18.00, 39, 'N');
INSERT INTO products VALUES (2, 'Chang', 10, 1, 19.00, 17, 'N');
INSERT INTO products VALUES (3, 'Aniseed Syrup', 20, 1, 10.00, 13, 'N');
INSERT INTO products VALUES (4, 'Chef Anton''s Cajun Seasoning', 20, 2, 22.00, 53, 'N');
INSERT INTO products VALUES (5, 'Chef Anton''s Gumbo Mix', 20, 2, 21.35, 0, 'Y');
INSERT INTO products VALUES (6, 'Grandma''s Boysenberry Spread', 30, 3, 25.00, 120, 'N');
INSERT INTO products VALUES (7, 'Northwoods Cranberry Sauce', 20, 3, 40.00, 6, 'N');
INSERT INTO products VALUES (8, 'Mishi Kobe Niku', 40, 4, 97.00, 29, 'Y');
INSERT INTO products VALUES (9, 'Ikura', 40, 4, 31.00, 31, 'N');
INSERT INTO products VALUES (10, 'Queso Cabrales', 40, 5, 21.00, 22, 'N');
COMMIT;

假设 category_id 10=‘Beverages’, 20=‘Condiments’, 30=‘Confections’, 40=‘Dairy Products’。

请为以下每个场景编写相应的SQL查询语句。

题目:

答案与解析:

SELECT ROWID, product_name FROM products;
SELECT product_id, product_name, unit_price FROM products WHERE ROWNUM <= 5;
SELECT product_name, unit_price
FROM (SELECT product_name, unit_price, ROWNUM AS rn
      FROM (SELECT product_name, unit_price
            FROM products
            ORDER BY unit_price DESC))
WHERE rn BETWEEN 3 AND 5;
SELECT category_id, COUNT(*) AS product_count, ROWNUM AS group_row_num
FROM products
GROUP BY category_id;
-- SELECT product_name, category_id, ROW_NUMBER() OVER (PARTITION BY category_id ORDER BY product_name) AS rn_in_category
-- FROM products;
SELECT product_name AS "调味品名称", units_in_stock AS "当前库存"
FROM products
WHERE category_id = 20;
SELECT * FROM products WHERE unit_price BETWEEN 20 AND 49.99;

使用比较运算符:

SELECT * FROM products WHERE unit_price >= 20 AND unit_price < 50;
SELECT product_id, product_name FROM products WHERE product_name LIKE 'Chef Anton%';
SELECT supplier_id, COUNT(*) AS discontinued_product_count
FROM products
WHERE discontinued = 'Y'
GROUP BY supplier_id
HAVING COUNT(*) > 0; -- 或者直接不加HAVING,如果没有已停产的供应商则不会显示
SELECT *
FROM products
ORDER BY category_id ASC, units_in_stock DESC NULLS LAST;
INSERT INTO products (product_id, product_name, category_id, unit_price, units_in_stock)
VALUES (product_pk_seq.NEXTVAL, 'New Test Product', 10, 15.00, 100);

SELECT product_pk_seq.CURRVAL FROM dual;

总结 

到此这篇关于Oracle数据库查询之单表查询的关键子句及其用法的文章就介绍到这了,更多相关Oracle单表查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文