博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

使用SQL检索、限制和排序数据

Posted on 2017-04-14 21:21  那家店  阅读(470)  评论(0)    收藏  举报

内容:

  • 执行基本的SELECT语句
  • 限制查询检索的行
  • 排序查询检索的行
  • 使用&符号替换变量
  • 连接多表

 

  Oracle服务器在一组特殊的关系表(数据字典)中存储每个表的信息,目的是管理它们。数据字典以集中、有序和结构化的格式存储数据库对象(表,索引,视图,图表,缺省值,规则,触发器,用户,函数等)的定义。

  关于不同数据库对象的元数据默认使用大写字母存储在数据字典中。

  表的定义与内容:

    表的定义包含一些信息:表名、表的所有者、列的细节、在磁盘上的物理存储大小。这些信息称为元数据。

    表的内容:储存在行中,称为数据

-- 命令disc[ribe] <schema>.tablename 查看表的结构元数据。虽然dual表属于sys模式,但是可是省略
-- dual是一个虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录。
SQL> discribe dual 名称 是否为空? 类型 ----------------------------- --------- ------------------- DUMMY VARCHAR2(1)

 

  机构化查询语言(Structure Query Language,SQL)中的select语句是一种强大的非言语语言结构,可用来从数据库表中检索信息。

  关系数据表构建在关系理论(relational theory)的数学基础上。关系表由称为关系代数(relationl algebra)的形式语言(英语:Formal language,是用精确的数学或机器可处理的公式定义的语言)进行运算。关系代数使用一些专门的术语:关系包含元组,而元组又有特性。Oracle术语:表包含行,而行又有列。来自关系理论的三个概念——投影、选择和连接概括了select语句的功能。

  • 投影表示对表中选择的列的限制。如表中有四个列,a、b、c和d,只选其中的a和b,这就叫投影。
  • 选择表示对从表中选择的行的限制。如表中有1、2和3,三个班级的数据,只选1班的数据行。
  • 连接表示查询中表之间的交互。通过主键和外键关系来连接表。

 

select语句的最基本形式支持列投影和创建算术、字符和日期表达式。能从结果集中删除重复行,排序。

SQL> SELECT ROWNUM, ROWID, 2*3, '这是字符串', sal + 2, 'my name : ' || ename AS "new_name"
      FROM emp
      WHERE deptno = 10;

    ROWNUM ROWID                     2*3 '这是字符串'         SAL+2  new_name
---------- ------------------ ---------- --------------- ---------- --------------------
     1 AAAR3dAAEAAAACXAAG          6 这是字符串            2452  my name : CLARK
     2 AAAR3dAAEAAAACXAAI          6 这是字符串            5002  my name : KING
     3 AAAR3dAAEAAAACXAAN          6 这是字符串            1302  my name : MILLER

-- select关键字后面紧跟着的不仅可以是要检索的列名,可以是任何有效的表达式,*表示所有列。

-- 数值右对齐,字符左对齐。

-- rownum 是查询结果集的行号,是个伪列,不是emp表中的数据。(数据库返回的所有行的集合称为结果集)
-- rowid Oracle数据库中的每一行都有一个唯一的行标识符,Oracle数据库内部用来存储行的物理位置。rowid是一个18位数,采用base-64编码。也是伪列
-- 查询可以直接做算术运算。
-- 也可以直接给字符串。
-- 列也可以执行算术运算。(+、-、*、/)
-- ||是连接操作符。
-- as起别名,输出的列名默认是大写的,使用双引号可以保存原样输出。

-- from关键字后面是要检索的表名。
-- where关键字后面是选择行的条件。

-- SQL语句以分号(;)结束。
SQL> SELECT DISTINCT deptno FROM emp;

    DEPTNO
----------
        30
        20
        10

SQL> SELECT DISTINCT deptno, ename
        FROM emp
        ORDER BY deptno, ename DESC;

    DEPTNO ENAME
---------- ----------
        10 MILLER
        10 KING
        10 CLARK
        20 SMITH
        20 SCOTT
        30 WARD
        30 TURNER

-- distinct 去除重复行,作用于其后的每个列

-- order by 排序,默认是升序asc。 上面以deptno升序排序之后,再以ename降序排序。数字升序1->9,日期升序2001->2009
-- null 可以使用关键字null fist(last)来规定排前面还是后面
-- order by 子句总是select语句的最后一句

-- order by 数字
SQL> select column1, column2, column3 ...... order by 2;
等价于order by column2

 

注意单引号与双引号的用法,单引号字符串,双引号列名。

 

当使用字面字符串是可能会包括单引号('),解决办法是在它前面再加一个单引号,或者使用引用操作符(q):

SQL> select ' Tom''s a boy ' from dual;

'TOM''SABOY'
-------------
 Tom's a boy


SQL> select q'<Tom's a boy>' from dual;

Q'<TOM'SABO
-----------
Tom's a boy

-- select字符串时,字符串包含单引号,就在单引号前加一个单引号。
-- 引用操作符(q) 其中(<)可以是任意符号,本身可以包含在字符串中,只有它后面没有单引号

 

NULL

空值代表没有数据,所有使用null值的算术运算总是返回null,not in (null,...)也返回空

SQL> select 'nihao' from dual where 'x' not in ('z','y',null);

  SQL> select 1 + null from dual;

-- 都返回空

 

LIKE操作符:

  • 下划线符号(_) 匹配一个字符。
  • 百分号字符(%) 匹配个字符。
SQL> select * from emp where ename like 'a\_%' escape '\';
-- 匹配以(a_)开头的ename, 上面的(\)可以是任意字符

 

笛卡尔积:

SQL> SELECT * FROM emp, dept;
-- 这样没有where条件的连接,得到笛卡尔积。
等价于:
SQL> SELECT * FROM emp CROSS JOIN dept;
-- SQL/92标准,交叉连接

 

据连接中使用的操作符的不同,连接条件可以分为两类:等值连接、不等值连接。

连接有3中类型:

  • 内连接:只有当连接中的列包含满足连接条件的值时才返回,如果有一行的连接条件中的一列为NULL,那么这行不返回。
  • 外连接:即使连接条件中的一列包含空值也返回这一行,分为左外连接、右外连接。
  • 自连接:连接同一张表,自己连接自己。

内连接:

复制代码
SQL/86标准:

SQL> select * from emp, dept where emp.deptno = dept.deptno; -- 在连接中使用等于操作符(=),等值连接 SQL> select * from emp, dept where emp.deptno > dept.deptno; -- 连接中使用了除等号之外的其他操作符,不等值连接


SQL/92标准:

SQL> select * from emp inner join dept on emp.deptno = dept.deptno and emp.no = dept.no;
-- inner join和on子句是SQL/92引人的,执行内连接,可以只用join
等价于:
SQL> select * from emp inner join dept using(deptno, no);
-- using 也是SQL/92引人的,用于等值连接,代替on。

SQL> select * from emp inner join dept using(dept) inner join management using(no);
-- 多表连接
复制代码

 外连接:

复制代码
左连接:

SQL> select * from emp, dept where emp.no = dept.no (+); -- (+)是Oracle专用外连接操作符
等价于:
SQL> select * from emp left outer join dept on emp.no = dept.no;
-- left outer join 是SQL/92标准,左连接,可以只用left join

右连接:
SQL> select * from emp, dept where emp.no (+) = dept.no;

SQL> select * from emp right outer join dept using(no);


全连接:
SQL> select * from emp full outer join dept using(no);
-- 全连接就是包括两边列为空值的行,(+)不能实现全连接

 

SQL*Plus 以&符号替换的形式提供了在运行时可以替换变量的功能:

-- 单个&符号替换
-- 替换单个变量
SQL> select &column from dual;
输入 column 的值:  sysdate
原值    1: select &column from dual               --这个新值旧值回显可以通过命令: set verify off关闭,set verify on 开启
新值    1: select sysdate from dual

SYSDATE
-------------------
2017-04-14 23:06:05

-- 替换一段语句
SQL> select &column;
输入 column 的值:  sysdate from dual
原值    1: select &column
新值    1: select sysdate from dual

SYSDATE
-------------------
2017-04-14 23:07:22

 SQL> select &column, sysdate, &column from dual;
 输入 column 的值: 'hello'
 输入 column 的值: 'hello2'
 原值 1: select &column, sysdate, &column from dual
 新值 1: select 'hello', sysdate, 'hello2' from dual

 'HELL SYSDATE 'HELLO
 ----- ------------------- ------
 hello 2017-04-14 23:39:30 hello2

--虽然两个都是&column,但并不一样


-- 双&符号(&&)替换

  SQL> select &&column, sysdate, &column from dual;
  输入 column 的值: 'hello'
  原值 1: select &&column, sysdate, &column from dual
  新值 1: select 'hello', sysdate, 'hello' from dual

  'HELL SYSDATE 'HELL
  ----- ------------------- -----
  hello 2017-04-14 23:42:50 hello

--使用&&只需要输入一次,后面同名的都是这个值了,当Oracle服务器遇到&&时,会将该变量定义为会话值,并不再提示输入后续引用的同名变量,直到会话结束(用户断开连接) 

使用define可以才看会话变量,就是&&变量:

-- 使用define查看
SQL> define;
...
...
DEFINE COLUMN          = "'hello'" (CHAR)

-- 使用define定义会话变量
SQL> define variable = value;

-- 使用undefine 删除会话变量
SQL> undefine column;

 如果字符串中要包含&字符,可以使用chr(38)表示&

SQL> select chr(38) from dual;
C
- &