MySQL_Ch_3

@BCKou

MySQL_Ch_3

1.多表连接查询

  1. 查询员工姓名和员工所在部门的编号

    select ename ,deptno from emp;
    
  2. 查询员工姓名, 所在部门名称

    select dname from dept where deptno = 10;
    
  3. 多表连接的基础 ——笛卡尔积

    – 两个集合A{a,b}、B{1,2,3}

    – 将两个集合中的元素逐一匹配形成一个新的集合

    A*B = {a1,a2,a3,b1,b2,b3}

    select * from emp,dept; 
    # 这种笛卡尔积的方式,会造成重复不必要数据
    

    – 实际应用需要在原有的笛卡尔积的基础上,设置必要的连接条件

    • 等值连接

      – 两张或者多张表之间,使用等号连接意义相同的两个列

      – 表.列名 哪张表下的哪一列

      select * from emp,dept where emp.deptno = dept.deptno;
      

      – 表设置别名(同名的表或者表名太长)

      – 建议使用空格的方式设置别名

      – 因为要适应于多种数据库;列名实际还是用as

      asoracle数据库中是不能用于标的别名的

      select * from emp e,dept d where e.deptno = d.deptno;
      

      – 查询月薪高于1500的员工姓名和部门名称

      select ename,dname,d.deptno
      # 如果列名是唯一,可以不用指明是哪一张表下的
      # 如果列名是重复,需要指定具体是哪一张表
      from emp e,dept d 
      where e.deptno = d.deptno 
      and sal >1500; -- 筛选条件
      

      – 表示两张以上的

      – 查询100号员工的姓名,所在部门名称,所在城市,所在国家,所在大区

      select e.first_name,d.department_name, l.city, c.country_id, r.region_id
      from employees e, departments d, locations l, countrise c, regions r
      where e.department_id = d.department_id
      and d.location_id = l.location_id
      and l.country_id = c.country_id
      and c.region_id = r.region_id
      and employee_id = 100 ; -- 筛选条件
      
    • 不等值连接

      – 不使用等号进行连接 < > <= >= !=(<>)

      – 查询员工姓名,月薪和工资的级别

      select ename, sal, grade
      from emp e,salgrade s
      where e.sal between s.losal and s.hisal;
      
    • 外连接

      • 左外连接
      • 右外连接

      – 查询员工姓名和其所在部门的名称,包含没有部门的员工

      错误写法
      select e.ename, d.dname
      from emp e, dept d
      where e.deptno = d.deptno
      or e.deptno is null; -- 错误写法,因为上面那个条件没有对or后的条件进行限制.
      

      – MySQL没有自己特有的外连接方式

      – 必须按照SQL99标准写法实现

      – 表A [left/right] [outer] join 表B on(...) join左边的表为左表,右边的表为右表

      – 查询员工姓名和其所在部门的名称,包含没有部门的员工

      select e.ename, d.dname
      from emp e left join dept d #[员工:XXX],[部门:null] ==>用左外连接
      on (e.deptno = d.deptno)
      
      select e.ename, d.dname
      from  dept d right join emp e #[部门:null],[员工:XXX], ==>用右外连接
      on (e.deptno = d.deptno)
      

      – 查询员工姓名和其所在部门的名称,包含没有员工的部门

      select e.ename, d.dname
      from emp e right join dept d #[员工:null],[部门:XXX] ==>用右外连接
      on (e.deptno = d.deptno)
      
      select d.dname, e.ename
      from dept d left join emp e #[部门:XXX],[员工:null] ==>用左外连接
      on (d.deptno = e.deptno)
      

      – 你想让哪部分多余的显示出来(即不是null值的那一部分),则对应哪侧的外连接

    • 自连接

      – 适用场景: 国家的行政体系 公司的组织结构

      – 层次关系

      – 查询员工姓名和对应的经理姓名

      –(姓名id和经理id是对应的,故可以自连接,第二张员工表的部分员工id可以看做经理id,因为经理也属于员工)

      错误写法

      select e1.ename as 员工姓名, e2.ename as 经理姓名
      from emp e1, emp e2 -- e1 员工表	e2 经理表
      where e1.empno = e2.mgr; -- 逻辑相反了,结果错误
      -- 错误的原因是:e2表中的mgr和e1表中的empno相等时,e2.mgr对应的e1.empno的e1.ename就是经理姓名,所以e1.ename就是经理姓名,同理e2.ename就是员工表里的员工.
      
      – 让员工的经理编号与经理的员工编号相等即可查询出来

      正确写法

      select e1.ename as 员工姓名, e2.ename as 经理姓名
      from emp e1, emp e2 -- e1 员工表	e2 经理表
      where e1.mgr = e2.empno;
      #员工表里的经理编号和经理表里的员工编号相等,逻辑才正确
      

      – 查询入职日期比其经理入职日期早的员工姓名和经理姓名

      select e1.ename as 员工姓名, e2.ename as 经理姓名
      from emp e1, emp e2 -- e1 员工表	e2 经理表
      where e1.mgr = e2.empno 
      and e1.hiredate < e2.hiredate;
      
      • SQL99标准语法

        • join ... on()

          1. 查询月薪高于1500的员工姓名和部门名称

            select e.ename, dname
            from emp e join dept d
            on(e.deptno = d.deptno)	#多表的连接条件
            where sal >1500;	#筛选条件
            
          2. 查询员工姓名,月薪和工资的级别

            select e.ename, sal, grade
            from emp e join salgrade s
            on(e.sal between s.losal and s.hisal);
            
          3. –自连接(内连接)

            select e1.ename,e2.ename
            from emp e1 inner join emp e2
            on(e.mgr = e2.empno);
            
          4. – 外连接(左外连接left outer和右外连接right outer)

            –(employee表和departments表)

            – 查询部门名称和其经理姓名,包含没有经理的部门

            select d.department_name, e.first_name , e.last_name
            from departments d left join employees e	#左外连接
            on (e.employee_id = d.manager_id);
            
            select d.department_name, e.first_name , e.last_name
            from employees e right join departments d
            on (e.employee_id = d.manager_id);
            

            – 左外连接和右外连接其实是等价的

          5. 全连接(MySQL 不支持)

            – full join … on (…)

            – 左外连接和右外连接再做一次多表连接

2.子查询

  • 在一个查询中嵌套的查询被称为子查询

  • where 后嵌套

  • from 后嵌套

  • having 后嵌套

  • select 后嵌套

  1. 按结构划分

    • 单行单列子查询

      • where 后嵌套

      1. – 查询和Scott同一个部门的其他员工信息

        select deptno from emp 
        where ename = 'scott';
        # #
        select * from emp
        where deptno = 20 and ename <> 'scott';
        

        组合查询

      select * from emp 
      where deptno = (select deptno from emp 
      			where ename = 'scott')
      and ename <> 'scott';
      

      – 外层我们可以称为主查询或者外查询

      – 内层我们成为内查询,或者子查询

      – 查询与scoot同一个部门,同一个经理的其他员工信息

      select * from emp 
      where deptno = (select deptno from emp 
      			where ename = 'scott')
      and mgr = (select mgr from emp 
      			where ename = 'scott')
      and ename <> 'scott';
      -- 三个查询,效率比较低
      
    • 单行多列子查询

      select * from emp 
      where (deptno, mgr) = (select deptno,mgr from emp 
      			where ename = 'scott')
      and ename <> 'scott';
      -- 注意
      -- 1) 单行多列 where后面的多列一定要有括号
      -- 2) where后的顺序要与子查询中查询出结果的顺序一致
      
    • 多行子查询(多行单列子查询、多行多列子查询)

      – 查询与Scott或King同一个部门的员工信息(多行单列子查询)

      select * from emp 
      where deptno in (select deptno from emp 
      			where ename = 'scott' or ename = 'King');
      
    • 子查询可以在哪些语句中使用

      – where(重要)

      – from(重要) 万能查询

      – 利用子查询的结果,将其当做一张表,

      – 与其他的表或者查询结果再次做多表连接

      外连接和等值连接区别(见最下总结)

      • from后的嵌套

      • from嵌套为万能嵌套

      • 例子: 查询员工的姓名,部门名称,员工的工资和其所在部门的平均工资:

        1)先查询部门名称和部门平均工资

        select d.dname, avg(sal), d.deptno
        from emp e join dept d 
        on(e.deptno = d.deptno)
        group by d.dname,d.deptno;
        

        2)将上述结果想象成一张表,再与emp做关联

        select e1.ename, t.dname, e1.sal, t.avgsal 
        from emp e1 join (select d.dname, avg(sal) as avgsal, d.deptno
        				  from emp e join dept d 
                          on(e.deptno = d.deptno)
        		          group by d.dname,d.deptno) t
        on(e1.deptno = t.deptno);
        
        #使用等值连接(内连接)
        select e1.ename,t.dname,e1.sal,t.avg_sal
        from emp e1 ,(select e.deptno,d.dname, avg(sal) as avg_sal
        					from emp e,dept d
        					group by e.deptno, d.dname) t
        where e1.deptno = t.deptno
        group by e1.ename,e1.sal;
        
        #######
        select e.ename, d.dname, e.sal, t.avg_sal
        from emp e,dept d,(select deptno,avg(sal) as avg_sal
        					from emp 
        					group by deptno) t
        where d.deptno = e.deptno
        group by e.ename,d.dname;
        
      • 查询员工姓名,职位,月薪,及其同职位的最高和最低月薪

        1)先查职位和同职位的最高、最低月薪

        select e2.job, max(e2.sal), min(e2.sal)
        from emp e2
        group by e2.job;
        

        2)利用上述结果与emp关联,查询剩余的列

        select e1.ename, e1.job, e1.sal, t.maxsal, t.minsal
        from emp e1 join (select e2.job, 
        				  max(e2.sal) as maxsal, 
                          min(e2.sal) as minsal
        				  from emp e2
        				  group by e2.job) t
        on(e1.job = t.job);                 
        
        #####使用等值连接
        select e.ename, e.job, e.sal, t.max_sal, t.min_sal
        from emp e,(select deptno, 
        				max(sal) as max_sal, 
                        min(sal) as min_sal
        				from emp
        				group by deptno) t
        where t.deptno = e.deptno
        group by e.ename,e.job,e.sal;
        
      • 查询月薪比自己职位的平均月薪高的员工信息

        select job,avg(sal)
        from emp
        group by job;
        
        select *
        from emp e1 join (select job, avg(sal) as avgsal
                          from emp
                          group by job) t
        on(e1.job = t.job)                  
        where e1.sal > t.avgsal;
        
        ###使用等值连接
        select e.*
        from emp e,(select deptno, avg(sal) as avg_sal
        				from emp
                        group by deptno) t
        where t.deptno = e.deptno
        and e.sal > t.avg_sal
        group by empno;
        
      • having后的嵌套(使用较少)

        where嵌套里涉及到分组函数时,一般使用having嵌套,因为where后不跟分组函数,要用having替换.

      • 查询部门平均工资高于MARTIN的部门编号

        select deptno
        from emp
        group by deptno
        having avg(sal) > (select sal from emp
                           where ename = 'MARTIN');
        
      • select后的嵌套 (基本不用)

      • 查询部门编号,部门名称,部门所在地,各个部门的人数,各个部门的平均月薪

        # 与相关子查询思考方式一致
        select d.deptno, d.dname, d.loc, 
        #(部门人数),
        (select count(*) from emp 
        where emp.deptno = d.deptno
        group by deptno) , 
        # (部门平均月薪)
        (select avg(sal) from emp 
        where emp.deptno = d.deptno
        group by deptno)
        from dept d;
        

练习

  1. 查询与Neena同一个经理的其他员工信息

    select * from employees
    where manager_id = (select manager_id from employees
    					where first_name = 'Neena')
    and first_name <> 'Neena';
    
  2. 查询比Jennifer Whalen月薪高的员工信息

    select * from employees
    where salary > (select salary from employees
    				where first_name = 'Jennifer'
                    and last_name = 'Whalen');
    

    查询比Jennifer月薪高的员工信息

    # ANY 和 ALL的使用
    select * from employees
    where salary > ANY(select salary from employees
    					where first_name = 'Jennifer' and last_name = 'Whalen');
    
  3. 查询员工姓名,月薪和其部门的平均月薪

    select e.first_name, e.last_name, e.salary, t.asal
    from employees e
    join (select department_id, avg(salary) as asal 
          from employees
          group by department_id) t
    on(e.department_id = t.department_id);
    
  4. 查询月薪高于其部门的平均月薪的员工信息

    select e.*
    from employees e
    join (select department_id,avg(salary) as avg_sal
          from employees
          group by department_id) t
    on(e.department_id = t.department_id)
    where e.salary > t.avg_sal;
    
  5. 查询司龄高于其部门平均司龄的员工信息

    select e.*
    from employees e
    join (select department_id,
          avg(year(curdate()) - year(hire_date)) as ayear
          from employees
          group by department_id) t
    on(e.department_id = t.department_id)
    where (year(curdate()) - year(hire_date)) > t.ayear;
    

外连接和内连接的区别

1、内联接(典型的联接运算,使用像 = 或 <> 之类的比较运算符)。

  • 包括相等联接和自然联接。
  • 内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行。
  • 例如,检索 students和courses表中学生标识号相同的所有行。

2、外联接

  • 外联接可以是左向外联接、右向外联接或完整外部联接。
  • 在 FROM子句中指定外联接时,可以由下列几组关键字中的一组指定:
    • 1)LEFT JOIN或LEFT OUTER JOIN
      左向外联接的结果集包括 LEFT OUTER子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。
    • 2)RIGHT JOIN 或 RIGHT OUTER JOIN
      右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。
    • 3)FULL JOIN 或 FULL OUTER JOIN
      完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。

3、交叉联接
交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积。
FROM 子句中的表或视图可通过内联接或完整外部联接按任意顺序指定;但是,用左或右向外联接指定表或视图时,表或视图的顺序很重要。有关使用左或右向外联接排列表的更多信息,请参见使用外联接。

例子:
-------------------------------------------------
a表 id name b表 id job parent_id
1 张3 1 23 1
2 李四 2 34 2
3 王武 3 34 4
a.id同parent_id 存在关系
--------------------------------------------------
1) 内连接

  select  a.*,b.*  from  a  inner  join  b   on  a.id=b.parent_id    

结果是
1 张3 1 23 1
2 李四 2 34 2

2)左连接

select  a.*,b.*  from  a  left  join  b   on  a.id=b.parent_id    

结果是
1 张3 1 23 1
2 李四 2 34 2
3 王武 null

3) 右连接

select  a.*,b.*  from  a  right  join  b   on  a.id=b.parent_id    

结果是
1 张3 1 23 1
2 李四 2 34 2
null 3 34 4

4) 完全连接

select  a.*,b.*  from  a  full  join  b   on  a.id=b.parent_id  

结果是
1 张3 1 23 1
2 李四 2 34 2
null    3 34 4
3 王武 null

一、交叉连接(CROSS JOIN)
交叉连接(CROSS JOIN):有两种,显式的和隐式的,不带ON子句,返回的是两表的乘积,也叫笛卡尔积。
例如:下面的语句1和语句2的结果是相同的。

语句1:隐式的交叉连接,没有CROSS JOIN。

SELECT O.ID, O.ORDER_NUMBER, C.ID, C.NAME
 FROM ORDERS O , CUSTOMERS C
 WHERE O.ID=1;

语句2:显式的交叉连接,使用CROSS JOIN。

SELECT O.ID,O.ORDER_NUMBER,C.ID,
 C.NAME
 FROM ORDERS O CROSS JOIN CUSTOMERS C
 WHERE O.ID=1;

语句1和语句2的结果是相同的,查询结果如下:

二、内连接(INNER JOIN)
内连接(INNER JOIN):有两种,显式的和隐式的,返回连接表中符合连接条件和查询条件的数据行。(所谓的链接表就是数据库在做查询形成的中间表)。
例如:下面的语句3和语句4的结果是相同的。

语句3:隐式的内连接,没有INNER JOIN,形成的中间表为两个表的笛卡尔积。

SELECT O.ID,O.ORDER_NUMBER,C.ID,C.NAME
 FROM CUSTOMERS C,ORDERS O
 WHERE C.ID=O.CUSTOMER_ID;

语句4:显示的内连接,一般称为内连接,有INNER JOIN,形成的中间表为两个表经过ON条件过滤后的笛卡尔积。

SELECT O.ID,O.ORDER_NUMBER,C.ID,C.NAME
 FROM CUSTOMERS C INNER JOIN ORDERS O ON C.ID=O.CUSTOMER_ID;

语句3和语句4的查询结果:

三、外连接(OUTER JOIN):外连不但返回符合连接和查询条件的数据行,还返回不符合条件的一些行。

  • 外连接分三类:左外连接(LEFT OUTER JOIN)、右外连接(RIGHT OUTER JOIN)和全外连接(FULL OUTER JOIN)。
    三者的共同点是都返回符合连接条件和查询条件(即:内连接)的数据行。不同点如下:
    1. 左外连接还返回左表中不符合连接条件单符合查询条件的数据行。
    2. 右外连接还返回右表中不符合连接条件单符合查询条件的数据行。
    3. 全外连接还返回左表中不符合连接条件单符合查询条件的数据行,并且还返回右表中不符合连接条件单符合查询条件的数据行。全外连接实际是上左外连接和右外连接的数学合集(去掉重复),即“全外=左外 UNION 右外”。
    4. 说明:左表就是在“(LEFT OUTER JOIN)”关键字左边的表。右表当然就是右边的了。在三种类型的外连接中,OUTER 关键字是可省略的。

下面举例说明:
语句5:左外连接(LEFT OUTER JOIN)

SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
 FROM ORDERS O LEFT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;

语句6:右外连接(RIGHT OUTER JOIN)

SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
 FROM ORDERS O RIGHT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;

注意:WHERE条件放在ON后面查询的结果是不一样的。例如:

语句7:WHERE条件独立。

SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
 FROM ORDERS O LEFT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID
 WHERE O.ORDER_NUMBER<>'MIKE_ORDER001';

语句8:将语句7中的WHERE条件放到ON后面。

SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
 FROM ORDERS O LEFT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID AND O.ORDER_NUMBER<>'MIKE_ORDER001';

从语句7和语句8查询的结果来看,显然是不相同的,语句8显示的结果是难以理解的。因此,推荐在写连接查询的时候,ON后面只跟连接条件,而对中间表限制的条件都写到WHERE子句中。

语句9:全外连接(FULL OUTER JOIN)

SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
 FROM ORDERS O FULL OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;

注意:MySQL是不支持全外的连接的,这里给出的写法适合Oracle和DB2。但是可以通过左外和右外求合集来获取全外连接的查询结果。下图是上面SQL在Oracle下执行的结果:

语句10:左外和右外的合集,实际上查询结果和语句9是相同的。

SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
 FROM ORDERS O LEFT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID
 UNION
 SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
 FROM ORDERS O RIGHT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;

语句9和语句10的查询结果是相同的,如下:

四、联合连接(UNION JOIN):这是一种很少见的连接方式。
Oracle、MySQL均不支持,其作用是:找出全外连接和内连接之间差异的所有行。这在数据分析中排错中比较常用。也可以利用数据库的集合操作来实现此功能。
语句11:联合查询(UNION JOIN)例句,还没有找到能执行的SQL环境。

SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
 FROM ORDERS O UNION JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID

语句12:语句11在DB2下的等价实现。还不知道DB2是否支持语句11呢!

SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
 FROM ORDERS O FULL OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID
 EXCEPT
 SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
 FROM ORDERS O INNER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;

语句13:语句11在Oracle下的等价实现。

SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
 FROM ORDERS O FULL OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID
 MINUS
 SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
 FROM ORDERS O INNER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;

查询结果如下:

五、自然连接(NATURAL INNER JOIN):说真的,这种连接查询没有存在的价值,既然是SQL2标准中定义的,就给出个例子看看吧。
自然连接无需指定连接列,SQL会检查两个表中是否相同名称的列,且假设他们在连接条件中使用,并且在连接条件中仅包含一个连接列。不允许使用ON语句,不允许指定显示列,显示列只能用*表示(ORACLE环境下测试的)。对于每种连接类型(除了交叉连接外),均可指定NATURAL。
下面给出几个例子。
语句14:

SELECT *
 FROM ORDERS O NATURAL INNER JOIN CUSTOMERS C;

语句15:

SELECT *
 FROM ORDERS O NATURAL LEFT OUTER JOIN CUSTOMERS C;

语句16:

SELECT *
 FROM ORDERS O NATURAL RIGHT OUTER JOIN CUSTOMERS C;

语句17:

SELECT *
 FROM ORDERS O NATURAL FULL OUTER JOIN CUSTOMERS C;

六、SQL查询的基本原理:两种情况介绍。
第一、单表查询:根据WHERE条件过滤表中的记录,形成中间表(这个中间表对用户是不可见的);然后根据SELECT的选择列选择相应的列进行返回最终结果。

第二、两表连接查询:对两表求积(笛卡尔积)并用ON条件和连接连接类型进行过滤形成中间表;然后根据WHERE条件过滤中间表的记录,并根据SELECT指定的列返回查询结果。

第三、多表连接查询:先对第一个和第二个表按照两表连接做查询,然后用查询结果和第三个表做连接查询,以此类推,直到所有的表都连接上为止,最终形成一个中间的结果表,然后根据WHERE条件过滤中间表的记录,并根据SELECT指定的列返回查询结果。

理解SQL查询的过程是进行SQL优化的理论依据。

七、ON后面的条件(ON条件)和WHERE条件的区别
ON条件:是过滤两个链接表笛卡尔积形成中间表的约束条件。

WHERE条件:在有ON条件的SELECT语句中是过滤中间表的约束条件。在没有ON的单表查询中,是限制物理表或者中间查询结果返回记录的约束。在两表或多表连接中是限制连接形成最终中间表的返回结果的约束。

从这里可以看出,将WHERE条件移入ON后面是不恰当的。推荐的做法是:

  • ON只进行连接操作,WHERE只过滤中间表的记录。

八、总结
连接查询是SQL查询的核心,连接查询的连接类型选择依据实际需求。如果选择不当,非但不能提高查询效率,反而会带来一些逻辑错误或者性能低下。下面总结一下两表连接查询选择方式的依据:

  1. 查两表关联列相等的数据用内连接。
  2. Col_L是Col_R的子集时用右外连接。
  3. Col_R是Col_L的子集时用左外连接。
  4. Col_R和Col_L彼此有交集但彼此互不为子集时候用全外。
  5. 求差操作的时候用联合查询。

多个表查询的时候,这些不同的连接类型可以写到一块。例如:

SELECT T1.C1,T2.CX,T3.CY
FROM TAB1 T1
    INNER JOIN TAB2 T2 ON (T1.C1=T2.C2)
    INNER JOIN TAB3 T3 ON (T1.C1=T2.C3)
    LEFT OUTER JOIN TAB4 ON(T2.C2=T3.C3);
WHERE T1.X >T3.Y;

上面这个SQL查询是多表连接的一个示范。

计算机中傅里叶变换

  • 傅里叶变换: 表示能将满足一定条件的某个函数表示成三角函数(正弦和/或余弦函数)或者它们的积分的线性组合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值