MySQL学习笔记(五)—— 子查询及联结
子查询:
子查询,即嵌套在其他查询中的查询。例如我们有这样几个表,顾客表,订单表,商品表,我们想知道有哪些客户买了商品A,那么我们就需要先查看哪些订单里包含了商品A,然后根据订单查出是哪些客户。
mysql> select cust_id from orders where order_num in (select order_num from orderitems where prod_id = '1');
+---------+
| cust_id |
+---------+
| 1001 |
| 1002 |
| 1003 |
+---------+
3 rows in set (0.01 sec)
子查询总是从内向外操作,在上面的SQL中实际上是执行了两个操作,先把有产品1的订单找出来,然后在从这些订单中把客户号给找出来。
在where子查询中可以嵌套多个子查询,可以通过查询编写出功能强大并且灵活的SQL语句,并且对于能嵌套的子查询的数目没有限制,不过在平时的日常使用中由于性能的限制,不能嵌套太多的子查询。
在where子句中使用子查询,应该保证select语句具有与where子句中相同数目的列,通常子查询将返回单个列并且与单个列匹配,但是也可以使用多个列。
作为计算字段使用子查询:
例:需要显示customers表中每个客户的订单总数,订单与相应的客户id存储在orders表中。
mysql> select cust_id,cust_name,(select count(*) from orders where orders.cust_id = customers.cust_id) as orders from customers order by cust_id;
+---------+-----------+--------+
| cust_id | cust_name | orders |
+---------+-----------+--------+
| 1001 | 张三 | 1 |
| 1002 | 李四 | 2 |
| 1003 | 王五 | 1 |
| 1004 | 赵六 | 2 |
| 1005 | 娄七 | 5 |
| 1006 | 吴八 | 2 |
+---------+-----------+--------+
6 rows in set (0.00 sec)
子查询中的where子句与前面使用的where子句稍有不同,select count(*) from orders where orders.cust_id = customers.cust_id,这条语句比较orders表中的cust_id和当前正从customers表中检索的cust_id,这种涉及到外部查询的子查询叫做相关子查询。如果我们不使用这种查询,即不适用完全限定的列名,那会出现什么样的结果。
mysql> select cust_id,cust_name,(select count(*) from orders where cust_id = cust_id) as orders from customers order by cust_id;
+---------+-----------+--------+
| cust_id | cust_name | orders |
+---------+-----------+--------+
| 1001 | 张三 | 13 |
| 1002 | 李四 | 13 |
| 1003 | 王五 | 13 |
| 1004 | 赵六 | 13 |
| 1005 | 娄七 | 13 |
| 1006 | 吴八 | 13 |
+---------+-----------+--------+
6 rows in set (0.00 sec)
这样一来返回的都是orders表总的订单数,因为没有把两个表中的cust_id进行匹配,MySQL将认为是将orders表中的cust_id进行自身的匹配,这样每次都是返回的都是总订单数,因为每次都是匹配的,就跟没有增加where条件一样。
联接表:
首先了解下外键,主键之前已经学习过了,但是一张表的来区分每一行的唯一标示,那么外键是什么呢?从上面的例子可以看出,在顾客表中cust_id是customers的主键,orders表中主键是order_num,在存储订单的信息的同时,也存储了顾客ID,利用这个ID能从顾客表中查出该订单顾客的信息,那么这个cust_id又叫做orders的外键。
外键:外键为某个表的一列,它包含了另一个表的主键值,定义了两个表之间的关系。
创建联接:
mysql> select cust_name,order_num from orders ,customers where customers.cust_id = orders.cust_id order by cust_name;
+-----------+-----------+
| cust_name | order_num |
+-----------+-----------+
| 吴八 | 10001012 |
| 吴八 | 10001013 |
| 娄七 | 10001009 |
| 娄七 | 10001006 |
| 娄七 | 10001011 |
| 娄七 | 10001010 |
| 娄七 | 10001007 |
| 张三 | 10001001 |
| 李四 | 10001003 |
| 李四 | 10001002 |
| 王五 | 10001004 |
| 赵六 | 10001008 |
| 赵六 | 10001005 |
+-----------+-----------+
13 rows in set (0.00 sec)
笛卡尔积:由没有联结条件的表关系返回的结果为笛卡尔积。检索出的行的数目僵尸第一个表中的行数乘以第二个表中的行数。
mysql> select cust_name,order_num from customers,orders;
+-----------+-----------+
| cust_name | order_num |
+-----------+-----------+
| 张三 | 10001001 |
| 李四 | 10001001 |
| 王五 | 10001001 |
| 赵六 | 10001001 |
| 娄七 | 10001001 |
| 吴八 | 10001001 |
| 张三 | 10001002 |
| 李四 | 10001002 |
| 王五 | 10001002 |
| 赵六 | 10001002 |
| 娄七 | 10001002 |
| 吴八 | 10001002 |
| 张三 | 10001003 |
| 李四 | 10001003 |
| 王五 | 10001003 |
| 赵六 | 10001003 |
| 娄七 | 10001003 |
| 吴八 | 10001003 |
| 张三 | 10001004 |
| 李四 | 10001004 |
| 王五 | 10001004 |
| 赵六 | 10001004 |
| 娄七 | 10001004 |
| 吴八 | 10001004 |
| 张三 | 10001005 |
| 李四 | 10001005 |
| 王五 | 10001005 |
| 赵六 | 10001005 |
| 娄七 | 10001005 |
| 吴八 | 10001005 |
| 张三 | 10001006 |
| 李四 | 10001006 |
| 王五 | 10001006 |
| 赵六 | 10001006 |
| 娄七 | 10001006 |
| 吴八 | 10001006 |
| 张三 | 10001007 |
| 李四 | 10001007 |
| 王五 | 10001007 |
| 赵六 | 10001007 |
| 娄七 | 10001007 |
| 吴八 | 10001007 |
| 张三 | 10001008 |
| 李四 | 10001008 |
| 王五 | 10001008 |
| 赵六 | 10001008 |
| 娄七 | 10001008 |
| 吴八 | 10001008 |
| 张三 | 10001009 |
| 李四 | 10001009 |
| 王五 | 10001009 |
| 赵六 | 10001009 |
| 娄七 | 10001009 |
| 吴八 | 10001009 |
| 张三 | 10001010 |
| 李四 | 10001010 |
| 王五 | 10001010 |
| 赵六 | 10001010 |
| 娄七 | 10001010 |
| 吴八 | 10001010 |
| 张三 | 10001011 |
| 李四 | 10001011 |
| 王五 | 10001011 |
| 赵六 | 10001011 |
| 娄七 | 10001011 |
| 吴八 | 10001011 |
| 张三 | 10001012 |
| 李四 | 10001012 |
| 王五 | 10001012 |
| 赵六 | 10001012 |
| 娄七 | 10001012 |
| 吴八 | 10001012 |
| 张三 | 10001013 |
| 李四 | 10001013 |
| 王五 | 10001013 |
| 赵六 | 10001013 |
| 娄七 | 10001013 |
| 吴八 | 10001013 |
+-----------+-----------+
78 rows in set (0.00 sec)
内部联结:inner join on
mysql> select cust_name,order_num from orders inner join customers on customers.cust_id = orders.cust_id order by cust_name;
+-----------+-----------+
| cust_name | order_num |
+-----------+-----------+
| 吴八 | 10001012 |
| 吴八 | 10001013 |
| 娄七 | 10001009 |
| 娄七 | 10001006 |
| 娄七 | 10001011 |
| 娄七 | 10001010 |
| 娄七 | 10001007 |
| 张三 | 10001001 |
| 李四 | 10001003 |
| 李四 | 10001002 |
| 王五 | 10001004 |
| 赵六 | 10001008 |
| 赵六 | 10001005 |
+-----------+-----------+
13 rows in set (0.00 sec)
下一章就是高级联结,需要更细致深入的学习。。。。
---------------------------------------------
Learning is endless......
---------------------------------------------
MySQL学习笔记(五)—— 子查询及联结的更多相关文章
- mysql学习笔记-- 多表查询之外键、表连接、子查询、索引
本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复 ...
- Entity Framework学习笔记(五)----Linq查询(2)---贪婪加载
请注明转载地址:http://www.cnblogs.com/arhat 在上一章中,我们使用了Linq对Entity Framework进行了一个查询,但是通过学习我们却发现了懒加载给我来的性能上的 ...
- MySql学习笔记(五) —— 存储过程
存储过程是MySql 5支持的特性,它是一组为了完成特定功能的SQL语句集,经过编译之后存储在数据库中,当需要使用该组SQL语句时用户只需要通过指定储存过程的名字并给定参数就可以调用执行它了,简而言之 ...
- MySQL学习笔记(五):MySQL表级锁和行级锁
一:概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...
- mysql学习笔记五 —— MHA
MySQL_MHA ABB(主从复制)-->MHA(实现mysql高可用.读写分离.脚本控制vip飘逸)-->haproxy(对slave集群实现分发,负载均衡)-->keepali ...
- mysql学习笔记11_12(查询)
1.建表和插入值 创建company数据库 创建 department表 create table department(d_id int(10) primary key not null uniqu ...
- MySQL学习笔记五:数据类型
MySQL支持多种数据类型,大致可以分为数值,日期/时间和字符类型. 数值类型 MySQL支持所有标准SQL数值数据类型,包括严格数值数据类型(INTEGER.SMALLINT.DECIMAL和NUM ...
- mysql学习 | LeetCode数据库简单查询练习
力扣:https://leetcode-cn.com/ 力扣网数据库练习:https://leetcode-cn.com/problemset/database/ 文章目录 175. 组合两个表 题解 ...
- 1.4(SQL学习笔记)分组、子查询、联结、组合查询
一.分组 建表及数据填充语句下载:链接: https://pan.baidu.com/s/1WHYafwqKJEKq1kDwCH_Zlg 提取码: 3wy4 1.1初识分组 分组是按照某一列,将该列中 ...
- MySql学习笔记(一)之DQL常用查询
MySql学习笔记(一)之DQL常用查询 前言:mysql是中小型的数据库软件,SQL语言分为DDL,DCL,DML,DQL四种,在这里重点讲解DQL的单表查询. 正文:在学习mysql单表查询之前, ...
随机推荐
- 深入理解Thread构造函数
上一篇快速认识线程 本文参考汪文君著:Java高并发编程详解. 1.线程的命名 在构造现成的时候可以为线程起一个名字.但是我们如果不给线程起名字,那线程会有一个怎样的命名呢? 这里我们看一下Threa ...
- 浅析 JavaScript 中的闭包(-------------------------------------------)
一.前言 对于 JavaScript 来说,闭包是一个非常强大的特征.但对于刚开始接触的初学者来说它又似乎是特别高深的.今天我们一起来揭开闭包的神秘面纱.闭包这一块也有很多的文章介绍过了,今天我就浅谈 ...
- Windows Server 2008R2 设置SMTP邮件转发服务
最近因业务需求在Windows Server 2008R2server上设置SMTP转发服务,主要是在业务审批过程中邮件通知相关人员审批情况, 1.在server上加入服务 2.打开服务 3.新建一个 ...
- iOS开发 解决使用AVAudioRecorder录制后转mp3解决音量小的问题
使用AVAudioRecorder录音后使用avplayer播放声音小,录音完后转成mp3格式的音频声音也小!!! 老板要求最基本的是不用把手机放到耳边听! 在StackOverFlow上查了一下,加 ...
- log4net菜鸟指南二----生成access和txt
前言 有可能目标计算机缺少某些组件,导致无法生成access文件,或者打不开文件,这时txt文件就可以方便的使用了 一,标准的控制台程序输出日志到access <?xml version=&qu ...
- HDU2256-Problem of Precision(矩阵构造+高速幂)
pid=2256">题目链接 题意:求sqrt(sqrt(2) + sqrt(3)) ^ 2n MOD 1024 思路: 代码: #include <iostream> # ...
- [Algorithms] Refactor a Loop in JavaScript to Use Recursion
Recursion is when a function calls itself. This self calling function handles at least two cases, th ...
- Jenkins 的安装与简单使用
一.安装 项目中接触到了jenkins感觉是一个不错的项目发布构建工具,自己就简单的学习了一下,记录一下方便以后使用 jenkin下载地址:https://jenkins-ci.org/ 我直接使 ...
- C#应该掌握的一些东西
C#应该掌握的一些东西 随着培训机构的增多,越来越多的人进入IT行业.那么对于我们这些自学出来,经验不够丰富的转行者来说,我们需要掌握最起码的一些东西,这对于面试很有用,而且在工作中也很常用.本人 ...
- bat+sqlcmd 批量执行脚本
Hello,此BAT脚本能够帮助开发者将某目录下全部SQL脚本按文件名称依次在指定数据库中批量执行. 不用忍受powershell invoke-sqlcmd 的笨重.在指执行时多一种选择. bat文 ...