4.5 数据表的外连接

本次课程我们将继续的学习数据表的连接。因为数据表的连接是分为内连接和外连接的。内连接的语法,还有一些练习,我们都是学习到了。那么本次课程咱们就开始学习数据表的外连接语法。首先我来解释一下为什么要使用外连接这种语法。咱们首先看一条记录,比如说陈浩这条记录之前,我们是插入到员工表里边的,是给他分配了具体的部门,但是我们要做外连接的练习,那我就可以把这个部门编号给设置为null. 原先它有具体的部门编号,但是我把它部门编号给改成null。那么改成null以后,就代表说,陈浩是一名临时的人员,他没有固定的部门编制。于是问题就来了。我想查询每名员工和他部门的名称的时候,如果使用内连接这种语法,连接员工表和部门表,就会漏掉陈浩这条记录。因为我们的连接条件是员工的部门编号,等于部门表的部门编号,所以说符合这个条件的记录会保留下来。不符合这个条件的记录,会筛选掉现在陈浩这个人,他没有部门deptno值。这个值是now值,所以你用内连接查询员工表和部门表的时候,陈浩这条记录会被筛选掉的,他不会出现在结果集里边。虽然说陈浩没有部门,但他也是属于这个公司的人,所以说我们想查询公司里面每名员工和他部门名称的时候,陈浩这个记录,是要保留下来的。

1. 外连接简介

外连接和内连接的区别在于,除了符合条件的记录之外,结果集中还会保留不符合条件的记录 ,不符合连接条件的记录是绝对不会出现在结果集里边的,而外连接就显得很特殊了。无论是否符合连接条件,数据是都会出现在结果集里边的。

比如说我们刚才想查询每名员工的部门信息,因为陈浩这个人没有部门编号。如果用内连接去查询员工表和部门表,那么陈浩就不符合连接条件,也就不会出现在结果集里边了,查询就漏掉了一名员工。如果换做外连接去查询,sql语句就得写成下面这个样子,在from子句里边写表连接的时候,连接的还是员工表和部门表。但是这个连接的关键字从join变成了left join

外连接分为左外连接和右外连接

left join就是左外连接

select 
e.deptno,d.dname,e.ename
from t_emp e left join t_dept d on e.deptno=d.deptno

2 左连接和右连接

左外连接就是保留左表所有的记录与右表做连接,如果右表有符合条件的记录就与左表连接。如果右表没有符合条件的记录,就用NULL与左表连接

如果用右外连接 right join来实现查询部门所有员工

select
e.deptno,d.dname,e.ename
from t_dept d right join t_emp e on d.deptno=e.deptno

外连接练习1:查询每个部门名称和人数

select
d.deptno,d.dname,count(e.ename)
from t_dept d left join t_emp e on d.deptno=e.deptno
GROUP BY d.deptno

外连接练习2:查询每个部门名称和人数?如果没有部门的员工用NULL代替

这道题要用关键字去做union关键字是把多个查询语句的结果进行合并的。当然是排除那些重复部分的内容。 我们去查询的时候,就是写好一个select语句,用括号给括起来。然后你要想跟其他的结果进行合并的时候,那后面再写上查询语句。然后两个查询语句用union关键字去连接就行了。有第三个这个查询的结果集,想要合并的话,那后面再往下写就行了。所以这个union合并多少个结果集的无所谓,关键就是这些结果集的字段的数量和字段的名称必须要相同。

UNION关键字可以将多个查询语句的结果集进行合并

(查询语句)  UNION  (查询语句)  UNION (查询语句)....

(select
d.deptno,d.dname,count(e.ename)
from t_dept d left join t_emp e on d.deptno=e.deptno
GROUP BY d.deptno)
union
(select
d.deptno,d.dname,count(e.ename)
from t_dept d right join t_emp e on d.deptno=e.deptno
GROUP BY d.deptno)

外连接练习3:查询每名员工编号,姓名,部门,月薪,工资等级,工龄,上司编号,上司姓名,上司部门?

select
e.empno as "员工编号",
e.ename as "姓名",
d.dname as "部门",
sal+ifnull(comm,0) as "月薪",
s.grade as "工资等级",
floor(datediff(now(),e.hiredate)/365) as "工龄",
t.empno as "上司编号",
t.ename as "上司姓名",
t.deptno as "上司部门"
from t_emp e left join t_dept d on e.deptno=d.deptno join t_salgrade s on e.sal between s.losal and s.hisal
left join 
(select
e3.empno,d2.dname,d2.deptno,e3.ename
from t_emp e3 join t_dept d2 on e3.deptno=d2.deptno) t on e.mgr=t.empno

FLOOR():向下取整

AS:命名别名

 

3. 外连接的注意事项

内连接只保留符合条件的记录,所以查询条件写在ON 子句和WHRER子句中的效果是相同的。但是外连接里,条件是写在WHERE子句里,符合条件的记录是会被过滤掉的,而不是保留下来

比如要 查询10部门的员工编号,员工姓名,部门名称

把条件写在 where中,不符合条件的会被过滤

select 
e.empno,e.ename,d.dname
from t_emp e left join t_dept d on e.deptno=d.deptno
where e.deptno=10

把条件写在 on中,不符合条件的也保留下来了

select 
e.empno,e.ename,d.dname
from t_emp e left join t_dept d on e.deptno=d.deptno
and e.deptno=10

### KEPServerEX V4.5 BACnet协议连接配置教程 KEPServerEX V4.5 提供了对 BACnet 协议的支持,适用于楼宇自动化和能源管理系统。以下是关于如何配置 KEPServerEX V4.5 与 BACnet 协议连接的详细说明。 #### 1. 安装 BACnet 驱动 在开始配置之前,确保已安装 KEPServerEX V4.5,并且在其驱动程序列表中包含 BACnet 驱动。如果未安装 BACnet 驱动,可以通过 KEPServerEX 的在线更新功能下载并安装该驱动[^1]。 #### 2. 创建 BACnet 设备 打开 KEPServerEX 软件,进入 **Channel**(通道)配置页面。点击 **Add Channel**,选择 BACnet 驱动程序。根据提示完成通道的创建,并设置以下参数: - **IP 地址**:指定目标设备的 IP 地址。 - **端口号**:默认为 47808(BACnet 标准端口)。 - **设备 ID**:输入目标设备的 BACnet 设备 ID[^1]。 #### 3. 配置标签映射 进入 **Device**(设备)配置页面,添加需要通信的 BACnet 设备。在设备配置中,定义标签映射规则,将 BACnet 数据点映射到 KEPServerEX 的标签系统中。具体步骤如下: - 点击 **Add Device**,输入设备名称和描述。 - 在 **Tags**(标签)页面中,手动添加或通过扫描发现 BACnet 数据点。 - 配置每个数据点的读写属性,例如对象类型、实例号、属性等[^1]。 #### 4. 测试连接 完成配置后,测试 BACnet 设备与 KEPServerEX 的连接是否正常。可以通过以下方法验证: - 在 KEPServerEX 的监控页面中查看设备状态。 - 使用 OPC 客户端或其他支持 BACnet 的工具读取数据点值,确保数据能够正确传输。 #### 5. 授权与运行 确保 KEPServerEX 已正确授权,否则可能无法使用高级功能或特定协议。按照授权步骤完成授权操作后,启动服务并监控运行状态。 ```python # 示例代码:通过 Python 读取 BACnet 数据点 from bacpypes.object import AnalogInputObject from bacpypes.app import BIPSimpleApplication from bacpypes.local.device import LocalDeviceObject def read_bacnet_data(device_id, object_type, instance): # 初始化本地设备 this_device = LocalDeviceObject( objectName="KEPServerEX", objectIdentifier=("device", 1), maxApduLengthAccepted=1024, segmentationSupported="noSegmentation", vendorIdentifier=1234, ) application = BIPSimpleApplication(this_device, "192.168.1.10/24") # 读取指定对象的数据 obj = application.get_object_by_id((object_type, instance)) if obj: return obj.presentValue else: return None # 示例调用 data = read_bacnet_data(1, "analogInput", 1) print(f"Read BACnet Data: {data}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值