SQL语句的高级查询整理

高级查询(多表连接查询)

    内连接:


    1.最常用也最重要的连接形式是内连接,有时候也被称作“EQUIJOIN”(等值连接)。

内连接根据连接谓词来组合两个表中的字段,以创建一个新的结果表。
SQL 查询会比较逐个比较表 1 和表 2 中的每一条记录,来寻找满足连接谓词的所有记录对。
当连接谓词得以满足时,所有满足条件的记录对的字段将会结合在一起构成结果表。

    外连接:


    左连接:

    1.左链接返回左表中的所有记录,即使右表中没有任何满足匹配条件的记录。
        这意味着,如果 ON 子句在右表中匹配到了 0 条记录,该连接仍然会返回至少一条记录,
        不过返回的记录中所有来自右表的字段都为 NULL。

    右连接:
    1.右链接返回右表中的所有记录,即是左表中没有任何满足匹配条件的记录。
        这意味着,如果 ON 子句在左表中匹配到了 0 条记录,该连接仍然会返回至少一条记录,
        不过返回的记录中所有来自左表的字段都为 NULL。

笛卡尔积的概念:

    1.笛卡尔积在SQL中的实现方式既是交叉连接(Cross Join)。
        所有连接方式都会先生成临时笛卡尔积表,笛卡尔积是关系代数里的一个概念,表示两个表中的每一行数据任意组合.

    2.(1)行数是两个表行数相乘的结果
       (2)列是两个表合集
    


SQL UNION 子句:

    1.SQL UNION 子句/运算符用于将两个或者更多的 SELECT 语句的运算结果组合起来。

在使用 UNION 的时候,每个 SELECT 语句必须有相同数量的选中列、相同数量的列表达式、相同的数据类型,
并且它们出现的次序要一致,不过长度不一定要相同。


2.UNION ALL 子句:

    UNION ALL 运算符用于将两个 SELECT 语句的结果组合在一起,重复行也包含在内。

UNION ALL 运算符所遵从的规则与 UNION 一致。


SQL 子查询:

    1.子查询(Sub Query)或者说内查询(Inner Query),也可以称作嵌套查询(Nested Query),
    是一种嵌套在其他 SQL 查询的 WHERE 子句中的查询。

    2.子查询用于为主查询返回其所需数据,或者对检索数据进行进一步的限制。

    3.子查询可以在 SELECT、INSERT、UPDATE 和 DELETE 语句中,同 =、<、>、>=、<=、IN、BETWEEN 等运算符一起使用。
    
    4.where ,from ,having,select 后面可以使用子查询的位置

    使用子查询必须遵循以下几个规则:

        1.子查询必须括在圆括号中。

        2.子查询的 SELECT 子句中只能有一个列,除非主查询中有多个列,用于与子查询选中的列相比较。

        3.子查询不能使用 ORDER BY,不过主查询可以。在子查询中,GROUP BY 可以起到同 ORDER BY 相同的作用。

        4.返回多行数据的子查询只能同多值操作符一起使用,比如 IN 操作符。
        

        5.SELECT 列表中不能包含任何对 BLOB、ARRAY、CLOB 或者 NCLOB 类型值的引用。

        6.子查询不能直接用在集合函数中。

        7.BETWEEN 操作符不能同子查询一起使用,但是 BETWEEN 操作符可以用在子查询中。


    SELECT,
    insert:

    子查询还可以用在 INSERT 语句中。INSERT 语句可以将子查询返回的数据插入到其他表中。
    子查询中选取的数据可以被任何字符、日期或者数值函数所修饰。

    update:
    
    子查询可以用在 UPDATE 语句中。当子查询同 UPDATE 一起使用的时候,既可以更新单个列,也可更新多个列。

    
自连接:

    1.一种虚拟方式。允许多次引用同一各表,该表就像独立的表一样,实际上创建了表的一个虚拟视图,允许多次使用这个虚拟视图。

    常用在自身是自引用的表,这类的表的一列指向了同一个表中的另一列。

    例如:
    有一张员工表,里面有三列,第一列为员工id列,第二列为姓名列,第三列为经理ID

        empoid  ename mgrid
        1    大海   null
        2    小王   1
        3       小溪   1
        4        大王  2

    现在想查一下每位员工的上级经理姓名
    SELECT e.ename, m.ename FROM emp e, emp m WHERE e.empnoid=m.mgrid

 层次查询:

    1.start with: 表示根记录的条件

    2.connect by: 指定了父记录行和子记录行之间的关系,在层次查询中,条件表达式必须使用prior操作符来指定父记录行

        3.connect by 不能包含子查询。
          prior是一个二元操作符,最常见的是用于列值相等的比较,它让Oracle使用对应列的父亲行的值。

    一个例子:Start with...Connect By子句递归查询一般用于一个表维护树形结构的应用。

    表如下所示:

    ID NAME PID
    1 111     0
    2 222     1
    3 333     0
    4 444     1
    5 555     2
    6 666     0
    9 999     2
        下面执行如下语句:
        
        SELECT  * FROM tbl_test START WITH ID = 1  CONNECT BY PRIOR ID = pid


        生成以下表:

        ID NAME PID
        1 111     0
        2 222     1
        5 555     2
        9 999     2
        4 444     1
        
        解析:
        1.(START WITH ID = 1)根记录条件为ID=1
        2.(CONNECT BY PRIOR ID = pid):由列ID与PID建立父子关系并进行比较,从ID为1开始,在PID列中寻找为1的行,可以找到ID为2和4,
           再将ID为2和4从PID中再寻找,又可以找到5和9,以上结果因此而来。    
      
    什么是伪列:

    1.伪列是在ORACLE中的一个虚拟的列。

    2.伪列的数据是由ORACLE进行维护和管理的,用户不能对这个列修改,只能查看。

    3.所有的伪列要得到值必须要显式的指定。

    4.最常用的两个伪列:rownum和rowid。

    
    ROWID(记录编号):
    1.是表的伪列,是用来唯一标识表中的一条记录,并且间接给出了表行的物理位置,定位表行最快的方式。

    2.主键:标识唯一的一条业务数据的标识。主键是给业务给用户用的。不是给数据库用的。

    3.记录编号rowid:标识唯一的一条数据的。主要是给数据库用的。类似UUID。

    
    ROWNUM(行号):

    1.是在查询操作时由ORACLE为每一行记录自动生成的一个编号。

    2.每一次查询ROWNUM都会重新生成。(查询的结果中Oracle给你增加的一个编号,根据结果来重新生成)

    3.rownum永远按照默认的顺序生成。(不受order by的影响)

    4.rownum只能使用 <、 <= ,不能使用 > 、>= 符号,原因是:Oracle是基于行的数据库,行号永远是从1开始,即必须有第一行,才有第二行。
    
    
    EXISTS:

    1.EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False
      EXISTS 指定一个子查询,检测 行 的存在。    
    
    2.EXISTS(包括 NOT EXISTS )子句的返回值是一个BOOL值。 EXISTS内部有一个子查询语句(SELECT ... FROM...),
    我将其称为EXIST的内查询语句。其内查询语句返回一个结果集。 EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。    

    3.一种通俗的可以理解为:将外查询表的每一行,代入内查询作为检验,
      如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,这一行行可作为外查询的结果行,否则不能作为结果。

原文地址:https://www.cnblogs.com/zuo72/p/8520566.html