首页 > 数据库 >SQL系列3-连表查询

SQL系列3-连表查询

时间:2023-09-18 16:12:53浏览次数:62  
标签:Customers cust Orders 联结 查询 连表 SQL id SELECT

SQL系列3-连表查询✅

子查询

嵌套子查询进行过滤:

SELECT cust_name, cust_contact         #顾客信息
FROM Customers
WHERE cust_id IN (SELECT cust_id       #订单所属顾客
 FROM Orders 
 WHERE order_num IN (SELECT order_num  #包含物品RGAN01的订单
 FROM OrderItems
 WHERE prod_id = 'RGAN01'));

子查询创建计算字段:

SELECT cust_name, 
 cust_state,
 (SELECT COUNT(*) 
 FROM Orders 
 WHERE Orders.cust_id = Customers.cust_id) AS orders
FROM Customers 
ORDER BY cust_name;

假如需要显示 Customers 表中每个顾客的订单总数

image-20230918094419349

虽然这里给出的样例代码运行良好,但它并不是解决这种数据检索的最有效方法。

联结表

使用联结表之前,需先了解关系表以及关系数据库。

现在有同一供应商生产的多种物品,那么在何处存储供应商名、地址、联系方法等供应商信息呢?

 同一供应商生产的每个产品,其供应商信息都是相同的,对每个产品重复此信息既浪费时间又浪费存储空间;

 如果供应商信息发生变化,例如供应商迁址或电话号码变动,只需修改一次即可;

 如果有重复数据(即每种产品都存储供应商信息),则很难保证每次输入该数据的方式都相同。不一致的数据在报表中就很难利用。

​ 关键是,相同的数据出现多次决不是一件好事,这是关系数据库设计的基础。关系表的设计就是要把信息分解成多个表,一类数据一个表。各表通过某些共同的值互相关联(所以才叫关系数据库)。

可伸缩性(scale):能够适应不断增加的工作量而不失败。设计良好的数据库或应用程序称之为可伸缩性好(scale well)

联结是一种机制,用来在一条SELECT语句中关联表,因此称之为联结。
使用特殊的语法,可以联结多个表返回一组输出,联结在运行时关联表中正确的行。
联结不是物理实体,它在实际的数据库中不存在,联结由MYSQL根据需要建立,它存在于查询的执行当中。
维护引用完整性:通过在表的定义中指定主键和外键来实现的。

内联结(连接)

内连接是系统默认的表连接,所以在 FROM 子句后可以省略 INNER 关键字,只用关键字 JOIN。 使用内连接后,FROM 子句中的 ON 子句可用来设置连接表的条件。 在 FROM 子句中可以在多个表之间连续使用 INNER JOIN 或 JOIN,如此可以同时实现多个表的内连接。内连接也被称为等值联结。

image-20230918135041635

自联结

此查询中需要的两个表实际上是相同的表,因此表table在FROM子句中出现了两次。为了避免二义性,使用了表别名。

  • 用自联结而不用子查询
    自联结通常作为外部语句用来替代从相同表中检索数据时使用的子查询语句,虽然最终的结果是相同的,但有时候处理联结远比处理子查询快得多。

  • 假如要给与 Jim Jones 同一公司的所有顾客发送一封信件。这个查询要求

    首先找出 Jim Jones 工作的公司,然后找出在该公司工作的顾客

SELECT c1.cust_id, c1.cust_name, c1.cust_contact
FROM Customers AS c1, Customers AS c2
WHERE c1.cust_name = c2.cust_name
AND c2.cust_contact = 'Jim Jones';

自然联结

无论何时对表进行联结,应该至少有一列不止出现在一个表中(被联结的列)。标准的联结(前一课中介绍的内联结)返回所有数据,相同的列甚至多次出现。自然联结排除多次出现,使每一列只返回一次。

怎样完成这项工作呢?答案是,系统不完成这项工作,由你自己完成它。自然联结要求你只能选择那些唯一的列,一般通过对一个表使用通配符(SELECT *),而对其他表的列使用明确的子集来完成。

外联结

许多联结将一个表中的行与另一个表中的行相关联,但有时候需要包含没有关联行的那些行。可以省略 OUTER 关键字

SELECT a.*,b.column2_name FROM table1 AS a LEFT JOIN table2 AS b ON a.column1 = b.column2;

如:

 对每个顾客下的订单进行计数,包括那些至今尚未下订单的顾客;

 列出所有产品以及订购数量,包括没有人订购的产品;

 计算平均销售规模,包括那些至今尚未下订单的顾客。

SELECT Customers.cust_id, Orders.order_num
FROM Customers
LEFT OUTER JOIN Orders ON Customers.cust_id = Orders.cust_id;

必须使用 RIGHT 或 LEFT 关键字指定包括其所有行的表(RIGHT 指出的是 OUTER JOIN 右边的表,而 LEFT 指出的是 OUTER JOIN左边的表)。上面的例子使用 LEFT OUTER JOIN 从 FROM 子句左边的表。

image-20230918140116407

image-20230918140133284

还有一个全外连接,MySQL目前不支持此种方式,可以用其他方式替代解决,不细说了。

它检索两个表中的所有行并关联那些可以关联的行。与左外联结或右外联结包含一个表的不关联的行不同,全外联结包含两个表的不关联的行。

(Customers 表)中选择所有行

image-20230918135605835

带聚集函数的联结

SELECT Customers.cust_id,
 COUNT(Orders.order_num) AS num_ord
FROM Customers
INNER JOIN Orders ON Customers.cust_id = Orders.cust_id
GROUP BY Customers.cust_id;

这条 SELECT 语句使用 INNER JOIN 将 Customers 和 Orders 表互相关联。

GROUP BY 子句按顾客分组数据,因此,函数调用 COUNT(Orders.order_num)

对每个顾客的订单计数,将它作为 num_ord 返回。

总结:

 注意所使用的联结类型。一般我们使用内联结,但使用外联结也有效。

 关于确切的联结语法,应该查看具体的文档,看相应的 DBMS 支持何

种语法(大多数 DBMS 使用这两课中描述的某种语法)。

 保证使用正确的联结条件(不管采用哪种语法),否则会返回不正确

的数据。

 应该总是提供联结条件,否则会得出笛卡儿积。

 在一个联结中可以包含多个表,甚至可以对每个联结采用不同的联结

类型。虽然这样做是合法的,一般也很有用,但应该在一起测试它们

前分别测试每个联结。这会使故障排除更为简单。

mysql系列(十三)SQL语句之联结表_sql语录联结表格_zhaojiaxing0216的博客-CSDN博客

可以完美总结联结这一仗知识点。

标签:Customers,cust,Orders,联结,查询,连表,SQL,id,SELECT
From: https://www.cnblogs.com/zheng-s/p/17712218.html

相关文章

  • sql系列5-组合查询
    sql系列5-组合查询✅利用UNION操作符将多条SELECT语句组合成一个结果集多数SQL查询只包含从一个或多个表中返回数据的单条SELECT语句。但是,SQL也允许执行多个查询(多条SELECT语句),并将结果作为一个查询结果集返回。这些组合查询通常称为并(union)或复合查询(compoundquer......
  • SQL系列4-插入更新与删除
    SQL系列4-插入更新与删除✅下面是许多SQL程序员使用UPDATE或DELETE时所遵循的重要原则。除非确实打算更新和删除每一行,否则绝对不要使用不带WHERE子句的UPDATE或DELETE语句。保证每个表都有主键(如果忘记这个内容,请参阅第12课),尽可能像WHERE子句那样使用它(......
  • 软件测试|MySQL CROSS JOIN:交叉连接的详细解析
    简介在MySQL数据库中,CROSSJOIN是一种用于生成两个或多个表的笛卡尔积的连接方法。CROSSJOIN不需要任何连接条件,它将左表的每一行与右表的每一行进行组合,从而生成一个包含所有可能组合的结果集。本文将详细介绍MySQL中的CROSSJOIN概念,并提供示例来加深理解。什么是CROSS......
  • 软件测试|MySQL INNER JOIN:内连接的详细解析
    简介在关系型数据库中,数据通常存储在多个表中,并且这些表之间可能存在关联关系。为了从多个表中检索相关数据,SQL提供了不同类型的连接操作,其中之一就是内连接(INNERJOIN)。本文将详细解析MySQL内连接的概念、语法和使用案例。什么是内连接(INNERJOIN)?内连接是一种用于从两个或多个表中......
  • SQL 将查询结果插入到另一张表中
    INSERTINTO如果两张表(导出表和目标表)的字段一致,并且希望插入全部数据,可以用这种方法:INSERTINTO目标表SELECT*FROM来源表WHERE条件;例如,要将test表插入到newTest表中,则可以通过如下SQL语句实现:INSERTINTOnewTestSELECT*FROMtest;如果只希望导入指定......
  • Ubuntu20.04安装Mysql8主从
    Ubuntu20.04安装Mysql8主从一.主数据库安装1.下载安装包并初始化数据库#进入目录cd/opt#下载安装包wgethttps://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz#解压tar-xvfmysql-8.0.20-linux-glibc2.12-x86_64.tar.xz......
  • SQLServer递归触发器在KES中的一次改造分析
    文章概要:某项目将数据从SQLSERVER迁移到KES。其中SQLSERVER中触发器用到了TRIGGER_NESTLEVEL()函数,KES并不能直接支持该函数。起初在分析该问题时想复杂了本文做了一次记录。实际上在kes兼容sqlsevrer基础语法,直接简单使用SYS_TRIGGER_DEPTH()替换TRIGGER_NESTLEVEL()函......
  • MySQL篇:第七章_详解mysql存储过程&函数
    存储过程含义:一组经过预先编译的sql语句的集合好处:1、提高了sql语句的重用性,减少了开发程序员的压力2、提高了效率3、减少了传输次数分类:1、无返回无参2、仅仅带in类型,无返回有参3、仅仅带out类型,有返回无参4、既带in又带out,有返回有参5、带inout,有返回有参注意:in、o......
  • DVWA靶场通关- SQL Injection(SQL注入)
    BruteForce(暴力(破解))、CommandInjection(命令行注入)、CSRF(跨站请求伪造)、     FileInclusion(文件包含)、FileUpload(文件上传)、InsecureCAPTCHA(不安全的验证码)、    SQLInjection(SQL注入)、SQLInjection(Blind)(SQL盲注)、XSS(DOM)(基于DOM树)、    XSS(Reflec......
  • MySQL篇:第六章_详解mysql视图
    周末有朋友来上海没来得及更新,特此更两篇以正身视图含义:理解成一张虚拟的表视图和表的区别: 使用方式 占用物理空间 视图 完全相同 不占用,仅仅保存的是sql逻辑 表 完全相同 占用视图的好处:1、sql语句提高重用性,效率高2、和表实现了分离,提高了安全性视......