`

SQL中exists函数用法,转为Hibernate的QBC查询

 
阅读更多

都知道这样的语句:

GROP TABLE user IF EXISTS

如果这个表存在,则删除一个表。但是在实际查询中,exists函数就用的少了。

今天做一个关联多表的查询,需要过滤掉满足某一条件的这些数据,大概的需求:


1、查询用户角色是学生(涉及到三个表:user、role、rel_user_role)的列表;

2、一个学生只能加入某老师创建的一个分组,不能同时加入一个老师创建的多个分组,但是可以加入不同老师创建的不同分组,即:这些学生加入的学习组中,不能有某一个老师创建的任何一个组;(设计到的表:group、rel_user_group、user)

3、或者学生没有加入任何组;

4、学生和老师都在同一个user表,用角色区别开。


尝试了各种方法,顺利得到学生创建的学习组的创建者id,但是苦死很久,也没想到如果判断这些创建者ID只要有一个值就不查出这些学生。

	SELECT teacher.* FROM `user` student INNER JOIN rel_user_role rur ON student.ID = rur.USER_ID inner JOIN role r ON ROLE_ID = r.ID AND r.ROLE_CODE = 'ROLE_STUDENT'
	INNER JOIN rel_user_group rug ON student.ID = rug.USER_ID INNER JOIN `group` g ON rug.GROUP_ID = g.ID
	INNER JOIN `user` teacher ON teacher.ID = g.CREATE_USER_ID 
	WHERE g.CREATE_USER_ID = 1

最后google了下,看到被人说可以用exists,尝试了下,果然好用:

只需要在查询学生的时候,让他所在组的创建者中,有一个ID等于特定值(如1)的这种条件不存在,就过滤了创建者ID为1的这些学生,剩下的学生就是我需要的数据,还有更方便的是,可以不管学生有没有学习组了,没有组,当然上面的这种条件也不成立。


最终SQL:

-- 查询是学生且他所在的学习组中没有创建者id为1的组的学生
SELECT student.* FROM `user` student,rel_user_role rur,role r
WHERE not EXISTS 
(
	-- 所在的学习组中没有创建者id为1的
	SELECT 0 FROM rel_user_role rur,role r,rel_user_group rug,`group` g
	WHERE 
				student.ID = rur.USER_ID 
		AND ROLE_ID = r.ID 
		AND r.ROLE_CODE = 'ROLE_STUDENT'
		AND student.ID = rug.USER_ID 
		AND rug.GROUP_ID = g.ID
		AND g.CREATE_USER_ID = 1
) 
-- 身份是学生
AND r.ID = rur.ROLE_ID 
AND student.ID = rur.USER_ID 
AND r.ROLE_CODE = 'ROLE_STUDENT'

转为Hibernate的QBC查询方式:
DetachedCriteria stuDc = DetachedCriteria.forClass(User.class, "u");
		stuDc.createAlias("roles", "role");
		stuDc.add(Restrictions.eq("role.roleCode", SystemConst.ROLE_STUDENT));

		// 不能在关联USER表查询group的创建老师user.
		DetachedCriteria rugDc = DetachedCriteria.forClass(RelUserGroup.class, "rug").createAlias("group", "group");
		rugDc.add(Property.forName("group.user.id").eq(UserUtil.getUser().getId())); // 组ID不能为当前登录老师的ID
		rugDc.add(Property.forName("rug.user.id").eqProperty(Property.forName("u.id")));// 关联User的id和RelUserGroup的ID
		// 这里的投影为子查询中SELECT出来的结果数据
		stuDc.add(Subqueries.notExists(rugDc.setProjection(Projections.property("rug.user.id"))));

最终将stuDc用于查询数据即可.

以下摘自网友博客,备查:


有一个查询如下:

1 SELECTc.CustomerId, CompanyName
2 FROMCustomers c
3 WHEREEXISTS(
4 SELECTOrderIDFROMOrders o
5 WHEREo.CustomerID = cu.CustomerID)

这里面的EXISTS是如何运作呢?子查询返回的是OrderId字段,可是外面的查询要找的是CustomerID和CompanyName字段,这两个字段肯定不在OrderID里面啊,这是如何匹配的呢?

EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False。

EXISTS 指定一个子查询,检测行的存在。语法:EXISTS subquery。参数 subquery 是一个受限的 SELECT 语句 (不允许有 COMPUTE 子句和 INTO 关键字)。结果类型为 Boolean,如果子查询包含行,则返回 TRUE。

    • 在子查询中使用 NULL 仍然返回结果集

这个例子在子查询中指定 NULL,并返回结果集,通过使用 EXISTS 仍取值为 TRUE。

1 SELECTCategoryName
2 FROMCategories
3 WHEREEXISTS (SELECTNULL)
4 ORDERBYCategoryNameASC
    • 比较使用 EXISTS 和 IN 的查询

这个例子比较了两个语义类似的查询。第一个查询使用 EXISTS 而第二个查询使用 IN。注意两个查询返回相同的信息。

1 SELECTDISTINCTpub_name
2 FROMpublishers
3 WHEREEXISTS
4 (SELECT*
5 FROMtitles
6 WHEREpub_id = publishers.pub_id
7 ANDtype ='business')
1 SELECTdistinctpub_name
2 FROMpublishers
3 WHEREpub_idIN
4 (SELECTpub_id
5 FROMtitles
6 WHEREtype ='business')
    • 比较使用 EXISTS 和 = ANY 的查询

本示例显示查找与出版商住在同一城市中的作者的两种查询方法:第一种方法使用 = ANY,第二种方法使用 EXISTS。注意这两种方法返回相同的信息。

1 SELECTau_lname, au_fname
2 FROMauthors
3 WHEREexists
4 (SELECT*
5 FROMpublishers
6 WHEREauthors.city = publishers.city)
1 SELECTau_lname, au_fname
2 FROMauthors
3 WHEREcity =ANY
4 (SELECTcity
5 FROMpublishers)
    • 比较使用 EXISTS 和 IN 的查询

本示例所示查询查找由位于以字母 B 开头的城市中的任一出版商出版的书名:

1 SELECTtitle
2 FROMtitles
3 WHEREEXISTS
4 (SELECT*
5 FROMpublishers
6 WHEREpub_id = titles.pub_id
7 ANDcityLIKE'B%')
1 SELECTtitle
2 FROMtitles
3 WHEREpub_idIN
4 (SELECTpub_id
5 FROMpublishers
6 WHEREcityLIKE'B%')
    • 使用 NOT EXISTS

NOT EXISTS 的作用与 EXISTS 正相反。如果子查询没有返回行,则满足 NOT EXISTS 中的 WHERE 子句。本示例查找不出版商业书籍的出版商的名称:

1 SELECTpub_name
2 FROMpublishers
3 WHERENOTEXISTS
4 (SELECT*
5 FROMtitles
6 WHEREpub_id = publishers.pub_id
7 ANDtype ='business')
8 ORDERBYpub_name

又比如以下 SQL 语句:

1 selectdistinct姓名fromxs
2 wherenotexists (
3 select*fromkc
4 wherenotexists (
5 select*fromxs_kc
6 where学号=xs.学号and课程号=kc.课程号
7 )

把最外层的查询xs里的数据一行一行的做里层的子查询。

中间的 exists 语句只做出对上一层的返回 true 或 false,因为查询的条件都在 where 学号=xs.学号 and 课程号=kc.课程号这句话里。每一个 exists 都会有一行值。它只是告诉一层,最外层的查询条件在这里成立或都不成立,返回的时候值也一样回返回上去。直到最高层的时候如果是 true(真)就返回到结果集。为 false(假)丢弃。

1 wherenotexists
2 select*fromxs_kc
3 where学号=xs.学号and课程号=kc.课程号

这个 exists 就是告诉上一层,这一行语句在我这里不成立。因为他不是最高层,所以还要继续向上返回。

select distinct 姓名 from xs where not exists (这里的 exists 语句收到上一个为 false 的值。他在判断一下,结果就是为 true(成立),由于是最高层所以就会把这行的结果(这里指的是查询条件)返回到结果集。

几个重要的点:

  • 最里层要用到的醒询条件的表比如:xs.学号、kc.课程号等都要在前面的时候说明一下select * from kc,select distinct 姓名 from xs
  • 不要在太注意中间的exists语句.
  • 把exists和not exists嵌套时的返回值弄明白
分享到:
评论

相关推荐

    sql中exists的用法

    SQL 中 EXISTS 的用法简介 exists 是 SQL 中最常用的子查询操作符之一,用于检测子查询是否返回至少一个记录。exists 的使用场景非常广泛,包括对多表之间的关系进行查询、检测记录的存在性等。 在 SQL 中,exists...

    Hibernate 函数 ,子查询 和原生SQL查询

    在Hibernate中,你可以使用内置的函数来处理数据,这些函数包括但不限于: 1. **Hibernate的数学函数**:如`max()`, `min()`, `sum()`, `avg()`和`count()`,它们用于对数据进行聚合操作,例如找出最大值、最小值、...

    exists SQL用法详解、exists和not exists的常用示例

    总之,`EXISTS`和`NOT EXISTS`是SQL中强大的工具,它们用于基于子查询是否有返回结果来决定主查询的执行。这两个操作符可以替代`IN`和`NOT IN`,在某些情况下提供更高的性能,尤其是在处理大量数据或复杂关联时。...

    SQL中exists的用法[借鉴].pdf

    SQL EXISTS 的用法详解 EXISTS 是 SQL 中的一个子句,用于判断是否存在满足条件的记录。...EXISTS 和 NOT EXISTS 子句都是 SQL 中重要的查询工具,它们可以帮助我们实现复杂的查询操作和判断子查询的结果。

    sql exists和not exists用法

    ### SQL EXISTS 和 NOT EXISTS 的用法详解 在SQL查询中,`EXISTS`与`NOT EXISTS`是非常实用的子查询操作符,它们主要用于检测是否存在满足一定条件的数据行。相较于`IN`、`NOT IN`等操作,`EXISTS`与`NOT EXISTS`...

    浅析SQL中WHERE EXISTS子查询.pdf

    浅析SQL中WHERE EXISTS子查询 SQL(Structured Query Language)是一种功能强大、通用的关系数据库语言,而SQL语言的核心是SELECT语句,其中WHERE子句的条件表达式表现得灵活而复杂,和谓词DISJunctive所形成的嵌套...

    sql server2005 exists使用方法

    ### SQL Server 2005 EXISTS 使用方法详解 #### 一、EXISTS 子句概述 在 SQL Server 2005 中,`EXISTS` 是一个非常实用的子句,用于检查子查询是否返回至少一行数据。如果子查询返回至少一行数据,则 `EXISTS` ...

    SQL中EXISTS与IN

    ### SQL中EXISTS与IN的区别及应用场景 #### EXISTS详解 **定义与原理** - **基本概念**:`EXISTS` 是 SQL 中的一个谓词,用于判断子查询是否有结果返回,而不是关心具体的返回值。它主要关注子查询是否至少有一行...

    关系代数中“除法”运算与SQL中带有exists子查询的对比教学.pdf

    关系代数中除法运算与SQL中exists子查询之间的联系,其实在某些特定的查询场景下,关系代数的除法运算可以转化为SQL中的exists子查询。例如,当你需要找出满足某些条件的主表记录,且这些记录必须关联到子表中所有...

    Delphi演示FileExists函数的用法.rar

    在Delphi编程环境中,`FileExists`函数是一个非常实用的工具,它用于检查指定路径的文件是否存在。这个函数是Delphi标准库中的一个部分,属于System.IOUtils单元,因此在使用前需要导入这个单元。本实例通过一个演示...

    SQL Exists语句的使用

    在SQL查询语句中,Exists语句的使用方式

    经典SQL查询总结关于Exists,not Exists.in ,not in效率的说明。

    本文将深入探讨 SQL 中 `EXISTS`, `NOT EXISTS`, `IN`, `NOT IN` 的使用场景及效率问题。 #### 一、Exists 和 Not Exists 的效率说明 **Exists** 和 **Not Exists** 子句通常用于检查子查询是否返回任何行,它们...

    sql in,exists,not in,not exists区别

    IN、EXISTS、NOT IN、NOT EXISTS 是 SQL 中四种常用的条件判断运算符,它们之间的区别主要体现在使用场景、执行效率和语法结构上。 IN IN 是一种条件判断运算符,用于判断某个值是否存在于一个列表中。其基本语法...

    SQL之EXISTS

    exists是用来判断是否存在的,当exists(查询)中的查询存在结果时则返回真,否则返回假。not exists则相反 它所在的查询属于相关子查询,即子查询的查询条件依赖于外层父查询的某个属性值,处理过程一般为: 取外层...

    function_exists函数详解

    例如,在 JavaScript 中,可以通过检查对象的属性来确定某个方法是否存在,而在 Python 中则可以使用 `callable()` 函数。 ### 总结 `function_exists()` 是 PHP 中一个简单而强大的工具,可以帮助开发者轻松地...

    SQL里的EXISTS与IN

    在SQL查询语言中,`EXISTS` 和 `IN` 子句都是非常常用且重要的操作符,它们被广泛应用于复杂的查询条件中,特别是当需要检查某个子查询是否返回结果时。根据给定的信息,本文将详细解析`EXISTS`与`IN`的区别以及如何...

    详解SQL EXISTS 运算符

    理解`EXISTS`和`NOT EXISTS`的用法对于优化SQL查询非常重要,因为它们通常比使用`IN`或`JOIN`操作符更有效率,特别是在处理大量数据时。`EXISTS`主要关注记录是否存在,而不需要返回具体的值,这使得它在处理复杂...

    试析SQL中EXISTS关键字的主要作用.pdf

    下面将详细分析EXISTS关键字在SQL中的应用: 1. 对空集的判定:在数据库操作中,判断某个子查询是否返回了空集是很有必要的,尤其是在存在全称量词的情况下。例如,如果我们想要查询所有参加了某门课程的学生名单,...

    判断SQL数据库中函数存储过程等是否存在的方法

    此外,了解SQL中的其他函数也是很重要的,例如: - **CHARINDEX**:用于在字符串中查找子字符串的位置。 - **分析函数**:如SQL Server中的`ROW_NUMBER()`、`RANK()`和`DENSE_RANK()`,用于对数据进行排序和分组。 -...

Global site tag (gtag.js) - Google Analytics