目录
[1. 通过列名查询所在的表](#1. 通过列名查询所在的表)
[2. 通过列名查询列的数据](#2. 通过列名查询列的数据)
[4. 使用PL/SQL块查询](#4. 使用PL/SQL块查询)
[4. 别名的命名规则:](#4. 别名的命名规则:)
[1. NVL函数](#1. NVL函数)
[2. NVL2函数](#2. NVL2函数)
[3. COALESCE函数](#3. COALESCE函数)
[4. 过滤空值](#4. 过滤空值)
[5. 注意事项](#5. 注意事项)
sql简介
结构化查询语言(Structured Query Language)简称SQL,结构化查询语言是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统:同时也是数据库脚本文件的扩展名。结构化查询语言是高级的非过程化编程语言,允许用户在高层数据结构上工作。它不要求用户指定对数据的存取方法,也不需要用户了解具体的数据存放方式,所以具有完全不同底层结构的不同数据库系统,可以实用相同的结构化查询语言作为数据输入与管理的接口。结构化查询语言可以嵌套,这使得它具有极大的灵活性和强大的功能。
DML(数据库操作语言)
其语句包括动词INSERT,UPDATE和DELETE。它们分别用于添加,修改和删除表中的行。也称为动作查询语言。
DDL(数据库定义语言)
其语句包括动词CREATE和DROP。在数据库中创建新表或删除表(CREATE TABLE 或 DROP TABLE):为表加入索引等。DDL包括许多与数据库目录中获得数据有关的保留字。它也是动作查询的一部分。
DCL(数据库控制语言)
它的语句通过GRANT 或 REVOKE 获得许可,确定单个用户和用户组对数据库对象的访问。某些RDBMS可用GRANT或REVOKE控制对表单个列的访问。
Select语句的语法格式
Oracle 数据库的 SELECT
语句用于从数据库表或视图中检索数据。以下是其基本语法格式:
sql
SELECT
[DISTINCT | ALL]
{ column_name | expression | aggregate_function(column_name) | ... }
[ , ... ]
FROM
table_name | view_name | (subquery)
[ [ AS ] alias_name ]
[ WHERE
search_condition ]
[ GROUP BY
group_by_expression [ , ... ] ]
[ HAVING
group_condition ]
[ ORDER BY
{ column_name | expression | position }
[ ASC | DESC ] [ , ... ] ]
[ FETCH FIRST [ row_count | PERCENT PERCENT ] [ ROWS | ROW ONLY ]
| OFFSET offset_value ROWS
| [ OFFSET offset_value ROWS ] FETCH NEXT [ row_count | PERCENT PERCENT ] [ ROWS | ROW ONLY ] ]
[ FOR UPDATE [ OF column_name [ , ... ] ] [ NOWAIT | WAIT n ] ];
说明:
SELECT
:指定要从数据库检索的列。DISTINCT
:可选。指定返回唯一的行。ALL
:默认。返回所有匹配的行,包括重复的行。column_name
:要检索的列的名称。expression
:可以是一个或多个列的组合、算术表达式等。aggregate_function(column_name)
:聚合函数,如SUM()
,AVG()
,MAX()
,MIN()
,COUNT()
等。FROM
:指定要从中检索数据的表或视图的名称。table_name
或view_name
:表或视图的名称。subquery
:子查询,它本身是一个SELECT
语句。alias_name
:为表或子查询指定的别名。WHERE
:指定要返回的行的搜索条件。GROUP BY
:根据一个或多个列对结果集进行分组。HAVING
:指定对分组后的结果进行过滤的条件。ORDER BY
:指定结果集的排序顺序。ASC
:升序排序(默认)。DESC
:降序排序。FETCH FIRST
:限制返回的行数。可以与OFFSET
一起使用以进行分页。OFFSET
:与FETCH NEXT
一起使用以跳过指定数量的行,通常用于分页。FOR UPDATE
:用于锁定检索的行以供后续更新。可以指定要锁定的列,或使用NOWAIT
或WAIT n
来控制锁定行为。
注意:Oracle 的不同版本可能支持不同的 SELECT
语句选项和语法。上述语法是 Oracle 数据库的一个通用版本,但具体细节可能因您使用的 Oracle 版本而异。
通过列名查询
在Oracle数据库中,如果你想要通过列名查询表或者查询列中的数据,你可以使用不同的方法。以下是一些常见的场景和相应的SQL语句:
1. 通过列名查询所在的表
如果你知道列名,但不确定它在哪个表中,你可以查询ALL_TAB_COLUMNS
、USER_TAB_COLUMNS
或DBA_TAB_COLUMNS
(如果你有足够的权限)视图。
例如,查询所有包含AGE
列的表:
sql
SELECT TABLE_NAME, OWNER
FROM ALL_TAB_COLUMNS
WHERE COLUMN_NAME = 'AGE'
ORDER BY TABLE_NAME;
注意:ALL_TAB_COLUMNS
会返回你有权访问的所有表和列的信息。如果你只想查询你拥有的表,可以使用USER_TAB_COLUMNS
。
2. 通过列名查询列的数据
如果你知道列名和表名,你可以使用SELECT
语句来查询列的数据。
例如,从STUDENT_BASE_INFO
表中查询AGE
列的数据:
sql
SELECT AGE FROM STUDENT_BASE_INFO;
3. 查询表的列名和数据类型
如果你想要查询指定表的所有列名和数据类型,你可以查询USER_TAB_COLS
或ALL_TAB_COLS
视图。
例如,查询STUDENT_BASE_INFO
表的所有列名和数据类型:
sql
SELECT COLUMN_NAME, DATA_TYPE, DATA_LENGTH, DATA_PRECISION, DATA_SCALE
FROM USER_TAB_COLS
WHERE TABLE_NAME = 'STUDENT_BASE_INFO'
ORDER BY COLUMN_ID;
注意:COLUMN_ID是一个可选的排序字段,它表示列在表中的顺序。你可以根据需要添加或省略它。
4. 使用PL/SQL块查询
在某些情况下,你可能想要编写一个PL/SQL块来遍历数据库中的所有表,并查找包含特定列名的表。这通常涉及动态SQL的使用,因为你需要根据查询结果构建和执行SQL语句。这种情况相对复杂,通常只在需要自动化或大规模查询时使用。
别名的用法
在Oracle数据库中,别名(Alias)是一种为表、列、函数等命名的方法,它可以使SQL语句更加简洁明了,提高代码的可读性和可维护性。以下是Oracle中别名的用法:
1.列别名:
在SELECT语句中,你可以为列指定一个别名,这样可以在结果集中以更友好的名称显示列。列别名的使用方法如下:
sql
SELECT column_name AS alias_name
FROM table_name;
或者,你可以简单地使用空格代替AS
关键字:
sql
SELECT column_name alias_name
FROM table_name;
例如,从employees
表中查询employee_id
和last_name
列,并将last_name
列重命名为lname
:
sql
SELECT employee_id, last_name AS lname
FROM employees;
2.表别名:
当查询涉及多个表时,为表指定别名可以使查询更加简洁。表别名的使用方法如下:
sql
SELECT table1.column_name, table2.column_name
FROM table1 AS alias1, table2 AS alias2
WHERE alias1.column_name = alias2.column_name;
或者,你可以简单地使用空格代替AS
关键字:
sql
SELECT table1.column_name, table2.column_name
FROM table1 alias1, table2 alias2
WHERE alias1.column_name = alias2.column_name;
例如,从employees
和departments
表中查询员工姓名和部门名称,并为这两个表指定别名e
和d
:
sql
SELECT e.last_name, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id;
3.别名在WHERE子句中的使用:
你可以在WHERE子句中使用列别名来过滤查询结果。但请注意,在某些数据库系统中,你可能不能在WHERE子句中直接使用列别名,因为这取决于查询的解析顺序。但是,在Oracle中,你可以在HAVING子句或ORDER BY子句中使用列别名。
4. 别名的命名规则:
- 别名的命名规则与变量名相同,可以包含字母、数字、下划线和美元符号,但必须以字母或下划线开头。
- 别名的长度不能超过30个字符。
- 别名不区分大小写(但在某些情况下,如创建对象时,Oracle可能会区分大小写)。
- 如果需要在多个查询中使用相同的别名,必须分别定义。
使用别名可以大大提高SQL语句的可读性和可维护性,特别是在处理复杂查询或涉及多个表的查询时。
消除重复数据
在Oracle数据库中,消除重复数据的方法有多种,以下是一些常见的方法:
1.使用DISTINCT关键字:
你可以使用DISTINCT
关键字来从查询结果中消除重复的行。但是,这通常用于选择不重复的数据,而不是删除表中的重复记录。
sql
SELECT DISTINCT column1, column2, ...
FROM table_name;
2.使用GROUP BY和HAVING子句:
你可以使用GROUP BY
子句对数据进行分组,并使用HAVING
子句来过滤出那些有重复数据的组。然后,你可以结合其他操作(如DELETE)来删除这些重复的数据。
sql
DELETE FROM table_name
WHERE (column1, column2, ...) IN (
SELECT column1, column2, ...
FROM table_name
GROUP BY column1, column2, ...
HAVING COUNT(*) > 1
);
注意:上面的DELETE语句可能因为Oracle的限制而无法直接执行(特别是在有外键约束的情况下)。你可能需要使用其他方法,如先创建一个临时表,然后删除原表数据,并将临时表中的数据重新插入。
- 使用ROWID:
你可以使用ROWID
来唯一标识表中的每一行,并通过比较ROWID
来删除重复的数据。
sql
DELETE FROM table_name a
WHERE ROWID NOT IN (
SELECT MIN(ROWID)
FROM table_name b
WHERE a.column1 = b.column1 AND a.column2 = b.column2 AND ...
);
在这个例子中,我们假设column1
, column2
, ... 是用于确定重复数据的列。这个DELETE语句会保留每组重复数据中的一行(基于ROWID的最小值),并删除其他行。
- 使用临时表和TRUNCATE/INSERT:
对于有大量重复数据的情况,你可以创建一个临时表来存储不重复的数据,然后清空原表并重新插入数据。
sql
CREATE TABLE temp_table AS SELECT DISTINCT * FROM table_name;
TRUNCATE TABLE table_name;
INSERT INTO table_name SELECT * FROM temp_table;
DROP TABLE temp_table;
请注意,在使用TRUNCATE
命令之前,请确保你已经备份了所有重要的数据,因为TRUNCATE
会删除表中的所有数据(并且不能回滚)。
- 使用EXISTS或NOT EXISTS子查询:
你还可以使用EXISTS
或NOT EXISTS
子查询来查找并删除重复的数据。这种方法可能比其他方法更复杂一些,但在某些情况下可能更有效。
- 创建唯一索引:
虽然这不是直接删除重复数据的方法,但你可以在表中创建唯一索引来防止将来插入重复的数据。如果表中已经存在重复的数据,那么创建唯一索引将会失败,并显示错误消息。在这种情况下,你需要先删除或合并重复的数据,然后再创建唯一索引。
查询中的四则运算
在Oracle数据库的查询中,四则运算(加、减、乘、除)可以在SELECT语句的表达式中直接使用。这些运算符与大多数编程语言中的运算符类似,并且遵循标准的数学运算优先级(即先乘除后加减,括号内的运算优先)。
以下是Oracle查询中四则运算的示例:
1. 加法运算
sql
SELECT column1 + column2 AS sum_result
FROM table_name;
在这个例子中,column1
和column2
是表中的两列,通过加法运算符+
将它们相加,并将结果命名为sum_result
。
2. 减法运算
sql
SELECT column1 - column2 AS difference_result
FROM table_name;
在这个例子中,column1
和column2
是表中的两列,通过减法运算符-
将它们相减,并将结果命名为difference_result
。
3. 乘法运算
sql
SELECT column1 * column2 AS product_result
FROM table_name;
在这个例子中,column1
和column2
是表中的两列,通过乘法运算符*
将它们相乘,并将结果命名为product_result
。
4. 除法运算
sql
SELECT column1 / column2 AS division_result
FROM table_name;
在这个例子中,column1
和column2
是表中的两列,通过除法运算符/
将它们相除,并将结果命名为division_result
。请注意,如果column2
的值为0,那么将会导致除以零的错误。
5. 注意事项
- 当在SELECT语句中进行四则运算时,确保操作数的数据类型是兼容的。例如,你不能将字符串和数字相加,除非字符串可以被隐式地转换为数字。
- 如果你的查询涉及多个表,并且你想对这些表中的列进行四则运算,你可能需要使用表的别名来区分这些列。
- 使用括号可以改变运算的优先级。例如,
(column1 + column2) * column3
将首先计算column1
和column2
的和,然后将结果乘以column3
。
空值问题
在Oracle数据库中,空值(NULL)是一个特殊的概念,用来表示字段中没有存储任何数据或数据的值未知。空值与零、空格或空字符串不同,它们表示不同的数据类型和含义。
处理Oracle中的空值问题是非常重要的,因为如果不妥善处理,可能会导致程序出现错误或不准确的结果。以下是一些关于Oracle空值问题的常见情况和处理方式:
空值的含义:
- 在Oracle中,空值表示一个字段没有存储任何数据。
- 它可以是一个未初始化的字段,也可以是一个被明确设置为NULL的字段。
- 空值与零、空格或空字符串是不同的,它们分别表示不同的数据类型和含义。
空值的处理方式:
- 使用COALESCE函数:该函数接受一个参数列表,并返回第一个非空的参数。如果所有参数都为空,则返回空值。例如,可以使用COALESCE函数来查找员工的多个联系电话,并返回第一个非空的电话号码。
- 使用NULLIF函数:该函数接受两个参数,如果第一个参数等于第二个参数,则返回空值;否则,返回第一个参数的值。这可以用于比较两个字段的值,并在它们相等时返回空值。
- 在查询中处理空值:在SELECT语句中,可以使用IS NULL或IS NOT NULL条件来检查字段是否为空值。这可以帮助你过滤或包含具有空值的行。
- 在插入或更新时处理空值:当插入或更新数据时,可以显式地将某个字段设置为NULL,以表示该字段没有值。但是,请注意,如果字段被定义为NOT NULL或具有其他完整性约束,则不能将其设置为NULL。
- 使用默认值:可以为字段设置默认值,以便在插入新行但未提供该字段的值时使用。这有助于避免空值问题,并确保每个字段都有一个有效的值。
注意事项:
- 在进行四则运算或比较操作时,如果涉及空值,可能会导致错误或不可预测的结果。因此,在编写查询或应用程序时,请务必考虑空值的可能性并妥善处理它们。
- 在设计数据库时,应仔细考虑是否需要允许空值,并根据需要为字段设置适当的完整性约束和默认值。这有助于确保数据的准确性和一致性。
查询空值
在Oracle数据库中,查询空值(NULL)通常使用IS NULL
条件。如果你想查询某个字段为空值的行,你可以将该字段与IS NULL
条件结合使用。
以下是一个简单的示例,演示如何在Oracle中查询空值:
sql
SELECT * FROM 表名 WHERE 列名 IS NULL;
在这个查询中,你需要将"表名"替换为你要查询的表的名称,将"列名"替换为你要检查空值的列的名称。
例如,如果你有一个名为employees
的表,并且你想查询phone_number
列为空值的所有员工,你可以使用以下查询:
sql
SELECT * FROM employees WHERE phone_number IS NULL;
这将返回phone_number
列为空值的所有employees
表的行。
另外,如果你想要查询非空值,你可以使用IS NOT NULL
条件:
sql
SELECT * FROM 表名 WHERE 列名 IS NOT NULL;
例如,查询phone_number
列非空值的所有员工:
sql
SELECT * FROM employees WHERE phone_number IS NOT NULL;
这将返回phone_number
列非空值的所有employees
表的行。
过滤空值
在Oracle中,当你想在查询中处理空值(NULL)时,可以使用多种方法,其中之一就是使用滤空函数,如NVL
、NVL2
、COALESCE
等。这些函数允许你替换或处理查询结果中的NULL值。
1. NVL函数
NVL
函数用于将NULL值替换为另一个值。其语法为:
sql
NVL(expression1, replace_with)
expression1
是要检查的表达式,如果它为NULL,则执行替换。replace_with
是当expression1
为NULL时要替换的值。
示例:
sql
SELECT NVL(phone_number, 'Unknown') AS phone_number_or_unknown
FROM employees;
在这个例子中,如果phone_number
列中的值为NULL,则结果集中的phone_number_or_unknown
列将显示为'Unknown'。
2. NVL2函数
NVL2
函数根据第一个参数是否为NULL来返回两个值中的一个。其语法为:
sql
NVL2(expression1, value_if_not_null, value_if_null)
expression1
是要检查的表达式。value_if_not_null
是当expression1
不为NULL时要返回的值。value_if_null
是当expression1
为NULL时要返回的值。
示例:
sql
SELECT NVL2(phone_number, 'Has Phone', 'No Phone') AS phone_status
FROM employees;
在这个例子中,如果phone_number
列中的值不为NULL,则phone_status
列将显示为'Has Phone';如果为NULL,则显示为'No Phone'。
3. COALESCE函数
COALESCE
函数返回参数列表中的第一个非NULL值。其语法为:
sql
COALESCE(expression1, expression2, ..., expressionN)
expression1
到expressionN
是要检查的表达式列表。函数将返回列表中的第一个非NULL值。如果所有值都为NULL,则返回NULL。
示例:
sql
SELECT COALESCE(phone_number, email, 'No Contact Info') AS contact_info
FROM employees;
在这个例子中,如果phone_number
列中的值不为NULL,则contact_info
列将显示电话号码;如果电话号码为NULL但email
列中的值不为NULL,则显示电子邮件地址;如果两者都为NULL,则显示'No Contact Info'。
4. 过滤空值
虽然这些函数本身不直接用于"过滤"空值(即从结果集中排除包含NULL的行),但它们允许你在结果集中处理或替换NULL值。如果你想要过滤掉包含NULL值的行,你应该在WHERE子句中使用IS NULL
或IS NOT NULL
条件。例如:
sql
SELECT *
FROM employees
WHERE phone_number IS NOT NULL; -- 过滤掉phone_number为NULL的行
5. 注意事项
- 当你使用不等于操作符(
<>
或!=
)来过滤数据时,这些操作符会忽略NULL值。也就是说,它们不会匹配NULL值。这就是为什么在过滤空值时,我们通常使用IS NULL
或IS NOT NULL
条件。 - 在比较或处理NULL值时,要小心,因为NULL与任何其他值的比较都会返回NULL(表示未知),这可能会导致查询结果不符合你的期望。因此,最好直接使用
IS NULL
或IS NOT NULL
条件来处理NULL值。
连接符
在Oracle数据库中,连接符(Concatenation Operator)用于将两个或多个字符串值连接在一起。在SQL中,Oracle使用||
作为连接符。
当你想要将两个或多个列的值、字符串常量或表达式连接成一个字符串时,你可以使用||
连接符。以下是一个简单的示例,展示了如何在Oracle中使用连接符:
sql
SELECT first_name || ' ' || last_name AS full_name
FROM employees;
在这个示例中,我们选择了employees
表中的first_name
和last_name
列,并使用||
连接符将它们与一个空格字符串连接在一起。结果集中的full_name
列将包含连接后的完整姓名。
请注意,连接符||
在Oracle SQL中是区分大小写的,因此必须使用小写字母。此外,当连接字符串时,如果其中一个操作数是NULL,则整个连接结果也将是NULL。为了避免这种情况,你可以使用NVL
函数将NULL值替换为一个空字符串或其他默认值。
除了连接符之外,Oracle还提供了其他字符串函数和操作符,用于处理字符串数据。这些函数和操作符可以帮助你执行各种字符串操作,如截取、替换、转换大小写等。你可以根据需要在查询中使用这些函数和操作符来处理和格式化字符串数据。