07-查询操作(DQL)-多表查询
一. 综述
查询操作主要从两个方面来说:单表查询和多表查询。 多表查询包括:笛卡尔积、外键约束、内连接查询、外链接查询、自连接查询。
二 . 案例设计
1. 设计产品表(product)。包括:主键id、产品名称(productName)、分类编号(dir_id)、零售价(salePrice)、供应商(supplier)、品牌(brand)、折扣(cutoff)、成本价(costPrice)。
设计产品产品编号表( productdir)。 包括:主键id、编号名称( dirName)、父id( parent_id) 。
设计产品库存表( productstock)。包括:主键id、产品id( product_id )、库存数量( storeNum)、上次进库时间(lastIncomeDate)、上次出库时间( lastOutcomeDate)、预警数量(warningNum)。
对应的SQL语句:
1 CREATE TABLE `product` (
2 `id` bigint(11) NOT NULL AUTO_INCREMENT,
3 `productName` varchar(50) DEFAULT NULL,
4 `dir_id` bigint(11) DEFAULT NULL,
5 `salePrice` double(10,2) DEFAULT NULL,
6 `supplier` varchar(50) DEFAULT NULL,
7 `brand` varchar(50) DEFAULT NULL,
8 `cutoff` double(2,2) DEFAULT NULL,
9 `costPrice` double(10,2) DEFAULT NULL,
10 PRIMARY KEY (`id`)
11 ) ENGINE=MyISAM AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;
12
13 -- ----------------------------
14 -- Records of product
15 -- ----------------------------
16 INSERT INTO `product` VALUES ('1', '罗技M90', '3', '90.00', '罗技', '罗技', '0.50', '35.00');
17 INSERT INTO `product` VALUES ('2', '罗技M100', '3', '49.00', '罗技', '罗技', '0.90', '33.00');
18 INSERT INTO `product` VALUES ('3', '罗技M115', '3', '99.00', '罗技', '罗技', '0.60', '38.00');
19 INSERT INTO `product` VALUES ('4', '罗技M125', '3', '80.00', '罗技', '罗技', '0.90', '39.00');
20 INSERT INTO `product` VALUES ('5', '罗技木星轨迹球', '3', '182.00', '罗技', '罗技', '0.80', '80.00');
21 INSERT INTO `product` VALUES ('6', '罗技火星轨迹球', '3', '349.00', '罗技', '罗技', '0.87', '290.00');
22 INSERT INTO `product` VALUES ('7', '罗技G9X', '3', '680.00', '罗技', '罗技', '0.70', '470.00');
23 INSERT INTO `product` VALUES ('8', '罗技M215', '2', '89.00', '罗技', '罗技', '0.79', '30.00');
24 INSERT INTO `product` VALUES ('9', '罗技M305', '2', '119.00', '罗技', '罗技', '0.82', '48.00');
25 INSERT INTO `product` VALUES ('10', '罗技M310', '2', '135.00', '罗技', '罗技', '0.92', '69.80');
26 INSERT INTO `product` VALUES ('11', '罗技M505', '2', '148.00', '罗技', '罗技', '0.92', '72.00');
27 INSERT INTO `product` VALUES ('12', '罗技M555', '2', '275.00', '罗技', '罗技', '0.88', '140.00');
28 INSERT INTO `product` VALUES ('13', '罗技M905', '2', '458.00', '罗技', '罗技', '0.88', '270.00');
29 INSERT INTO `product` VALUES ('14', '罗技MX1100', '2', '551.00', '罗技', '罗技', '0.76', '300.00');
30 INSERT INTO `product` VALUES ('15', '罗技M950', '2', '678.00', '罗技', '罗技', '0.78', '320.00');
31 INSERT INTO `product` VALUES ('16', '罗技MX Air', '2', '1299.00', '罗技', '罗技', '0.72', '400.00');
32 INSERT INTO `product` VALUES ('17', '罗技G1', '4', '155.00', '罗技', '罗技', '0.80', '49.00');
33 INSERT INTO `product` VALUES ('18', '罗技G3', '4', '229.00', '罗技', '罗技', '0.77', '96.00');
34 INSERT INTO `product` VALUES ('19', '罗技G500', '4', '399.00', '罗技', '罗技', '0.88', '130.00');
35 INSERT INTO `product` VALUES ('20', '罗技G700', '4', '699.00', '罗技', '罗技', '0.79', '278.00');
CREATE TABLE `productdir` (
`id` bigint(11) NOT NULL auto_increment,
`dirName` varchar(30) default NULL,
`parent_id` bigint(11) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `productdir` VALUES ('1', '鼠标', null);
INSERT INTO `productdir` VALUES ('2', '无线鼠标', '1');
INSERT INTO `productdir` VALUES ('3', '有线鼠标', '1');
INSERT INTO `productdir` VALUES ('4', '游戏鼠标', '1');
CREATE TABLE `productstock` (
`id` bigint(11) NOT NULL auto_increment,
`product_id` bigint(11) default NULL,
`storeNum` int(10) default NULL,
`lastIncomeDate` datetime default NULL,
`lastOutcomeDate` datetime default NULL,
`warningNum` int(10) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- ----------------------------
-- Records
-- ----------------------------
INSERT INTO `productstock` VALUES ('1', '1', '182', '2015-03-12 20:33:00', '2015-03-12 20:33:04', '20');
INSERT INTO `productstock` VALUES ('2', '2', '27', '2015-03-02 20:33:28', '2015-03-09 20:33:40', '20');
INSERT INTO `productstock` VALUES ('3', '3', '89', '2015-02-28 20:34:13', '2015-03-12 20:34:19', '20');
INSERT INTO `productstock` VALUES ('4', '5', '19', '2015-03-01 20:34:43', '2015-03-12 20:34:48', '20');
INSERT INTO `productstock` VALUES ('5', '6', '3', '2015-02-01 20:35:12', '2015-03-02 20:35:16', '5');
INSERT INTO `productstock` VALUES ('6', '7', '2', '2015-02-02 20:35:59', '2015-02-27 20:36:05', '3');
INSERT INTO `productstock` VALUES ('7', '8', '120', '2015-03-12 20:36:31', '2015-03-12 20:36:33', '20');
INSERT INTO `productstock` VALUES ('8', '9', '58', '2015-03-02 20:36:50', '2015-03-12 20:36:53', '20');
INSERT INTO `productstock` VALUES ('9', '11', '28', '2015-03-02 20:37:12', '2015-03-12 20:37:15', '20');
INSERT INTO `productstock` VALUES ('10', '12', '8', '2015-03-02 20:37:35', '2015-03-09 20:37:38', '5');
INSERT INTO `productstock` VALUES ('11', '13', '3', '2015-03-02 20:37:58', '2015-03-12 20:38:01', '5');
INSERT INTO `productstock` VALUES ('12', '14', '6', '2015-03-02 20:38:20', '2015-03-07 20:38:23', '5');
INSERT INTO `productstock` VALUES ('13', '15', '2', '2015-02-02 20:38:38', '2015-02-24 20:38:44', '5');
INSERT INTO `productstock` VALUES ('14', '16', '3', '2015-02-02 20:39:05', '2015-02-06 20:39:09', '3');
INSERT INTO `productstock` VALUES ('15', '17', '49', '2015-03-02 20:39:36', '2015-03-12 20:39:40', '20');
INSERT INTO `productstock` VALUES ('16', '18', '14', '2015-03-02 20:39:57', '2015-03-09 20:40:01', '10');
INSERT INTO `productstock` VALUES ('17', '20', '7', '2015-03-02 20:40:22', '2015-03-03 20:40:25', '5');
三. 多表查询
1. 笛卡尔积
多表查询会产生笛卡尔积。 假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。实际运行环境下,应避免使用全笛卡尔集。
解决笛卡尔积最有效的方法:等值连接。
-- 需求:查询所有的货品信息+对应的货品分类信息
SELECT productName,dirName FROM product,productdir WHERE dir_id = productdir.id
2. 外键约束
主键约束(PRIMARY KEY): 约束在当前表中,指定列的值非空且唯一.
外键约束(FOREIGN KEY): A表中的外键列. A表中的外键列的值必须参照于B表中的某一列(B表主键).
注意:在MySQL中,InnoDB支持事务和外键.修改表的存储引擎为InnDB。
格式:ALTER TABLE 表名 ENGINE='InnoDB'。
主表:数据可以独立存在,就是被参考的表。 productdir
从表:表中的数据,必须参照于主表的数据。product
注意:在删除表的时候,先删除从表,再删除主表。
3. 多表查询详解
多表查询包括三类:内连接查询(隐式内连接和显示内连接)、外连接查询 (左外链接、右外链接、全链接 )、自连接查询。
(1). 内连接
隐式内连接:查询出来的结果是多表交叉共有的。
格式:
显式内连接:
格式:
注意:在做等值连接的时候,若A表中的和B表中的列相同,可以缩写为:
需求:查询所有商品的名称和分类名称:
隐式内连接:
SELECT p.productName,pd.dirName FROM product p,productdir pd WHERE p.dir_id = pd.id
显示内连接:
SELECT p.productName,pd.dirName FROM product p INNER JOIN productdir pd ON p.dir_id = pd.id
显示内连接:
SELECT p.productName,pd.dirName FROM product p JOIN productdir pd ON p.dir_id = pd.id 需求: 查询零售价大于200的无线鼠标
SELECT * FROM product p,productdir pd WHERE p.dir_id = pd.id AND p.salePrice >200 And
pd.dirName ='无线鼠标' SELECT * FROM product p JOIN productdir pd on p.dir_id = pd.id WHERE p.salePrice >200 And
pd.dirName ='无线鼠标' 需求: 查询每个货品对应的分类以及对应的库存
SELECT p.productName,pd.dirName,ps.storeNum
FROM product p,productdir pd,productstock ps
WHERE p.dir_id = pd.id AND p.id = ps.product_id SELECT p.productName,pd.dirName,ps.storeNum
FROM product p
JOIN productdir pd on p.dir_id = pd.id
JOIN productstock ps on p.id = ps.product_id 需求: 如果库存货品都销售完成,按照利润从高到低查询货品名称,零售价,货品分类(三张表).
select *, (p.salePrice - p.costPrice) * ps.storeNum lirun
FROM product p,productdir pd,productstock ps
WHERE p.dir_id = pd.id AND p.id = ps.product_id
ORDER BY lirun DESC select *, (p.salePrice - p.costPrice) * ps.storeNum lirun
FROM product p
JOIN productdir pd on p.dir_id = pd.id
JOIN productstock ps on p.id = ps.product_id
ORDER BY lirun DESC
(2). 外连接查询
左外连接:查询出JOIN左边表的全部数据,JOIN右边的表不匹配的数据用NULL来填充。
右外连接:查询出JOIN右边表的全部数据,JOIN左边的表不匹配的数据用NULL来填充。
eg: A LEFT JOIN B 等价于 B RIGHT JOIN A
-- 外链接
# 查询所有商品的名称和分类名称
左连接:
SELECT * FROM product p LEFT JOIN productdir pd ON p.dir_id = pd.id
-- 等价于
SELECT * FROM productdir pd RIGHT JOIN product p ON p.dir_id = pd.id
右连接:
SELECT * FROM product p RIGHT JOIN productdir pd ON p.dir_id = pd.id
(3). 自连接查询:把一张表看成两张表来做查询
07-查询操作(DQL)-多表查询的更多相关文章
- MySQL数据库查询操作进阶——多表查询
多表查询 在大部分情况下,我们用到的表都是彼此相关联的,所以我们会有相当大的需求用到跨表的查询,这个时候我们就需要将相关联的表连起来做多表查询. 多表查询分为连表查询和子查询,连表查询即将相关联的表连 ...
- 06-查询操作(DQL)-单表查询
一. 综述 查询操作主要从两个方面来说:单表查询和多表查询. 单表查询包括:简单查询.过滤查询.结果排序.分页查询.聚集函数. 二 . 案例设计 1. 设计产品表(product).包括:主键 ...
- (七)MySQL数据操作DQL:多表查询2
(1)准备环境 1)创建员工表 mysql> create table company.employee6( -> emp_id int auto_increment primary ke ...
- (七)MySQL数据操作DQL:单表查询1
(1)单表查询 1)环境准备 mysql> CREATE TABLE company.employee5( id int primary key AUTO_INCREMENT not null, ...
- mysql查询操作之单表查询、多表查询、子查询
一.单表查询 单表查询的完整语法: .完整语法(语法级别关键字的排列顺序如下) select distinct 字段1,字段2,字段3,... from 库名.表名 where 约束条件 group ...
- mysql重点,表查询操作和多表查询
表单查询 1. 完整的查询语句语法 select distinct(* or 字段名 or 四则运算 )from 表名 where 条件 group by 条件 having 条件 order by ...
- 百万年薪python之路 -- MySQL数据库之 MySQL行(记录)的操作(二) -- 多表查询
MySQL行(记录)的操作(二) -- 多表查询 数据的准备 #建表 create table department( id int, name varchar(20) ); create table ...
- mysql第四篇:数据操作之多表查询
mysql第四篇:数据操作之多表查询 一.多表联合查询 #创建部门 CREATE TABLE IF NOT EXISTS dept ( did int not null auto_increment ...
- DQL多表查询
DQL多表查询 一.多表查询实现多个表之间查询数据 1.交叉连接笛卡尔积:A表中的每一行匹配B表中的每一行基本结构:select [数据库名1.]表名1,属性名1,......, [数据库名.]表名. ...
随机推荐
- pycharm修改注释颜色
原来的注释是红色的,看着跟报错似的.. 还有flask中html文件的注释,我修改了Django的注释颜色,flask也就改了 也可以直接点击下面的代码,哪里难看点哪里
- 「CodeForces 581D」Three Logos
BUPT 2017 Summer Training (for 16) #3A 题意 给你三个矩形,需要不重叠不留空地组成一个正方形.不存在输出-1,否则输出边长和这个正方形(A,B,C表示三个不同矩形 ...
- python活用isdigit方法显示系统进程
如何利用字符串的内置函数isdigit(),判断一个字符串是一个纯数字.如果是纯数字会返回True,否则返回fasle. 利用isdigit()方法编写一个python脚本显示所有系统进程pid.os ...
- 【Nowcoder71E】组一组(差分约束,最短路)
[Nowcoder71E]组一组(差分约束,最短路) 题面 Nowcoder 题解 看到二进制显然就直接拆位,那么区间的按位或和按位与转成前缀和之后,可以写成两个前缀和的值的差的大小关系,那么直接差分 ...
- 【原】本地仓库推送到远程仓库:fatal: refusing to merge unrelated histories
最近,在操作git的时候,遇到各种问题,下面总结一下. 最开始,我不是先把远程仓库拉取到本地 ,而是直接在本地先创建一个仓库,再git remote add添加远程仓库. 当然,gitee官方还是有操 ...
- 使用ss命令对tcp连接数和状态的监控性能优化
之前对tcp的监控采用netstat命令,发现在服务器繁忙的时候效果不理想,这个命令占用大量的cpu有时候高达90%以上,可能会导致业务的不稳定,所以改用ss命令对脚本进行优化 对tcp连接数和状态的 ...
- Ubuntu Server 18.04 网络设置不生效的解决
在Ubuntu18.04中,传统的配置/etc/network/interfaces已无用https://www.cnblogs.com/dunitian/p/6658578.html 新方法:修改 ...
- WebService学习总结(一)——WebService的相关概念
一.序言 大家或多或少都听过 WebService(Web服务),有一段时间很多计算机期刊.书籍和网站都大肆的提及和宣传WebService技术,其中不乏很多吹嘘和做广告的成 分.但是不得不承认的是W ...
- 再谈 javascript 数组去重
前言 数组去重方法老生常谈,既然是常谈,我也来谈谈 双层循环 也许我们首先想到的是使用 indexOf 来循环判断一遍,但在这个方法之前,让我们先看看最原始的方法: var array = [1,1, ...
- JAVA基础语法 我的学习记录
1.标识符 Java所有的组成部分都需要名字.类名.变量名以及方法名都被称为标识符. 关于Java标识符,有以下几点需要注意: 所有的标识符都应该以字母(A-Z或者a-z),美元符($).或者下划线( ...