标题: access查询语句求解释! [打印本页] 作者: lyzcl 时间: 2021-2-1 22:31 标题: access查询语句求解释! 查询语句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;
作者: lyzcl 时间: 2021-2-1 22: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却提示我输入参数,这是怎么回事?作者: djt 时间: 2021-2-4 15:10
不出错作者: lyzcl 时间: 2021-2-6 12:14
自己查了些资料,对这个问题有所理解,自问自答吧:
这个问题来源于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)这条查询结果。作者: wuwu200222 时间: 2021-2-25 10:15
学习