设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
查看: 3627|回复: 5
打印 上一主题 下一主题

[查询] access查询语句求解释!

[复制链接]

点击这里给我发消息

跳转到指定楼层
1#
发表于 2021-2-1 22:31:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
查询语句1:
SELECT Contacts.FirstName, Contacts.LastName
FROM Contacts
WHERE (((Contacts.FirstName) In (SELECT [FirstName] FROM [Contacts] As Tmp GROUP BY [FirstName],[LastName] HAVING Count(*)>1  And [LastName] = [Contacts].[LastName])))
ORDER BY Contacts.FirstName, Contacts.LastName;

结果(正确)如下:


查询语句2:
SELECT Contacts.FirstName, Contacts.LastName
FROM Contacts
WHERE (((Contacts.FirstName) In (SELECT [FirstName] FROM [Contacts] As Tmp GROUP BY [FirstName],[LastName] HAVING Count(*)>1  )))
ORDER BY Contacts.FirstName, Contacts.LastName;

结果(错误)如下:

为什么会出现这样的不同结果呢?2个查询语句的区别就在于加了“And [LastName] = [Contacts].[LastName]”这一段。不知道该怎么理解?
按我的理解,这2条查询语句都是先筛出一个tmp临时表,然后FirstName从这个tmp临时表里筛选,搞不清楚怎么能实现把LastName不同的记录给去掉的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 分享淘帖 订阅订阅

点击这里给我发消息

2#
 楼主| 发表于 2021-2-1 22:33:04 | 只看该作者
我疑惑的有3点:
1. 查询2里面,GROUP BY [FirstName],[LastName] HAVING Count(*)>1 似乎已经是对[FirstName]和[LastName]2个字段进行聚合了,理应在tmp临时表里排除pete teeth(只有一行)的记录;
2. 查询1里面,And [LastName] = [Contacts].[LastName] 这段语句的作用是什么,得出的结果是什么,又是如何进一步与前面的语句共同作用的?
3. 无论查询1还是查询2,得到的tmp临时表都应该只有[FirstName] 一个字段,也就是说不管是否排除了pete teeth这个只有一行的记录,tmp表的内容都是annie,pete,sue这3条记录。再从中匹配[FirstName],查询1和查询2的结果应该都是一样的(都包含pete teeth)?

点击这里给我发消息

3#
 楼主| 发表于 2021-2-1 22:33:33 | 只看该作者
我尝试着把in后面的字段截取出来单独运行,
1)当运行SELECT [FirstName] FROM [Contacts] As Tmp GROUP BY [FirstName],[LastName] HAVING Count(*)>1 时,得到annie,pete,sue这3条记录的tmp临时表(如果加上count(*) as count后,count字段显示pete moss的计数为2,并排除了pete teeth,说明这段语句是对2个字段的聚合)。
2)当运行SELECT [FirstName] FROM [Contacts] As Tmp GROUP BY [FirstName],[LastName] HAVING Count(*)>1  And [LastName] = [Contacts].[LastName]时,access却提示我输入参数,这是怎么回事?
4#
发表于 2021-2-4 15:10:16 | 只看该作者
不出错
回复

使用道具 举报

点击这里给我发消息

5#
 楼主| 发表于 2021-2-6 12:14:24 | 只看该作者
自己查了些资料,对这个问题有所理解,自问自答吧:
这个问题来源于access查询向导生成的重复项查询,我在网上搜索,通过“access重复性查询”搜到了一篇文章,里面提到access重复性查询向导生成的SQL语句不容易理解,另外给出了用INNER JOIN方式的SQL查询,容易看懂。文章链接如下:
《论坛不让发连接》
该文章没有直接对access生成的SQL语句进行解读,但提到了之所以不易理解,是因为涉及到了“子查询”。所以我又看了些有关“SQL子查询”的内容。终于在一定程度上理解了。下面是我的理解:

查询1是access生成的SQL语句:SELECT Contacts.FirstName, Contacts.LastName
FROM Contacts
WHERE (((Contacts.FirstName) In (SELECT [FirstName] FROM [Contacts] As Tmp GROUP BY [FirstName],[LastName] HAVING Count(*)>1  And [LastName] = [Contacts].[LastName])))
ORDER BY Contacts.FirstName, Contacts.LastName;
之前我不理解,是因为对“SQL关联子查询”的运行方式不了解。按照初级的编程语言的理解,我想当然的以为这条SQL语句应该先运行IN()里面的内容,返回结果用于上层Where()语句,最后再把返回结果应用于最外层的select语句。这样去理解,会遇到无法解决的困惑。
而“SQL关联子查询”真正的运行方式是这样的:外层先把查询结果每次输送一条给子查询。这个例子里,外层查询出的是全部记录,首先把第一条记录(Annie,matter)传输给子查询,此时的子查询中,SELECT [FirstName] FROM [Contacts] As Tmp GROUP BY [FirstName],[LastName] HAVING Count(*)>1  And [LastName] = [Contacts].[LastName]语句首先有了限定条件:[LastName]=“matter”,又对[FirstName],[LastName]进行聚合,实际上的结果只有“Annie”这一条记录。这个结果输送给上一层,相当于WHERE “Annie” In {"Annie"},语句成立,外层查询SELECT Contacts.FirstName, Contacts.LastName
FROM Contacts成功输出了第一条查询结果(Annie,matter)。
然后第二条记录、第三条记录……依次执行。当遇到(pete,teeth)这条记录时,子查询SELECT [FirstName] FROM [Contacts] As Tmp GROUP BY [FirstName],[LastName] HAVING Count(*)>1  And [LastName] = "teeth"由于聚合的结果不大于1,返回的结果是空。所以对外层查询来说,(pete,teeth)这条记录就被排除了。

查询2是我改的,把子查询中我当初理解不了的And [LastName] = [Contacts].[LastName]去掉了。
SELECT Contacts.FirstName, Contacts.LastName
FROM Contacts
WHERE (((Contacts.FirstName) In (SELECT [FirstName] FROM [Contacts] As Tmp GROUP BY [FirstName],[LastName] HAVING Count(*)>1  )))
ORDER BY Contacts.FirstName, Contacts.LastName;
这样一来,子查询和外层查询的关联就没有了。我不清楚整个SQL语句运行时是否还是每次由外层传递给子查询一条记录。不管如何,此时当遇到(pete,teeth)这条记录时,查询SELECT [FirstName] FROM [Contacts] As Tmp GROUP BY [FirstName],[LastName] HAVING Count(*)>1因为少了一个限制,聚合后返回给上层的结果应该是{Annie,Pete,Sue}而不再是空。所以就错误的输出了(pete,teeth)这条查询结果。

点击这里给我发消息

6#
发表于 2021-2-25 10:15:31 | 只看该作者
学习
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-11-29 02:04 , Processed in 0.098881 second(s), 31 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表