• 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). 自连接查询:把一张表看成两张表来做查询

           

  • 相关阅读:
    Serialize and Deserialize Binary Tree
    sliding window substring problem汇总贴
    10. Regular Expression Matching
    《深入理解计算机系统》(CSAPP)读书笔记 —— 第七章 链接
    程序员如何写一份合格的简历?(附简历模版)
    9个提高代码运行效率的小技巧你知道几个?
    《深入理解计算机系统》(CSAPP)读书笔记 —— 第六章 存储器层次结构
    24张图7000字详解计算机中的高速缓存
    《深入理解计算机系统》(CSAPP)实验四 —— Attack Lab
    《深入理解计算机系统》(CSAPP)读书笔记 —— 第五章 优化程序性能
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/7192202.html
Copyright © 2020-2023  润新知