日常工作小结(九)

    今天在一个业务处理流程中,需要对三张表的进行关联查询。之前碰到最多也就是两张表的联合查询,昨天和同学交流的时候,他说在写SQL时,关联查询最好少用等值连接。而现在我也想突破下常规,换中写法试试。在读大学的时候,记得学过数据库这么课,但是当时对编程几乎没有什么理解,那些知识现在也很模糊了,基本上都还给老师了。公司办公环境又不允许接入互联网,只能硬着头皮慢慢回想了。由于本项目使用了Hibernate处理数据的持久化,还要尽量接近面向对象查询这种思路。

    先简单抽象下业务情景:

Device(设备)
    List<Conference> conferences;

Conference(会议)
    Device device;
    List<User> users;
    Status status; //会议的一个状态值(进行、结束)

User(用户)
    List<Conference> conferens;

//映射关系
A和B是多对一的双向关联, B维护关联关系
B和C是多对多的双向关联,通过一张中间表,使用双方主键建立关联关系

//目的
假如User现在有4个用户:u1 u2 u3 u4
Device有一台:d1
Device下举办过3场会议: 
    c1[u1, u2, u3]  已结束
    c2[u2, u3]  进行中
    c3[u2, u4] 进行中
现在要查的就是Device为d1的设备下,所有没有正在参加会议的用户
其实就是所有的users与 d1设备下正在参加会议的用户的差集
在上情形就是:[u1, u2, u3, u4] 差 ([u2, u3] 并 [u2, u4]) = u1

    最后转换成HQL语句就是

SELECT u from User u where u not in (
    select User tu from tu left join tu.conferences c 
    where c.status=? and c.device.deviceId=?)

    虽然可以查出结果,但是效率到底怎么样,心里还是没底。下面在复习下那几种关联查询。

1. inner join:在表中存在至少一个匹配时,INNER JOIN 关键字返回行

    Device表

device_id
device_name
1
设备1
2
设备2

    Conference表

conference_id
conference_name
device_id
1
会议1
1
2
会议2
4
3
会议3
1
4
会议4
3

    SQL:

SELECT d.device_name, c.conference_name from device d inner join conference c 
    on d.device_id=c.device_id;

    结果集:

设备1
会议1
设备1
会议3

    INNER JOIN 关键字在表中存在至少一个匹配时返回行。如果 "Device" 中的行在 "Conference" 中没有匹配,就不会列出这些行。

2. left join:会从左表 (Device) 那里返回所有的行,即使在右表 (Conference) 中没有匹配的行

SELECT d.device_name, c.conference_name from device d left join conference c 
    on d.device_id=c.device_id;

    结果集:

设备1
会议1
设备1
会议3
设备2

3. right join: 会从右表 (Device) 那里返回所有的行,即使在左表 (Conference) 中没有匹配的行

SELECT d.device_name, c.conference_name from device d right join conference c 
    on d.device_id=c.device_id;

    结果集:

设备1
会议1

会议2
设备1
会议3

会议4

4. full join:全连接,这个对比上面的就很好理解了。

你可能感兴趣的:(关联查询,等值连接)