关于在ACCESS SQL

时间:2016-12-07 17:34:04

标签: sql ms-access

我希望弄清楚SQL语句中的HAVING组件是如何工作的,特别是对于具有多个连接的SQL语句。请考虑以下SQL select语句:

SELECT 
   p.id,
   p.first_name as [First Name], 
   p.last_name as [Last Name]
FROM
   ( [tbl_person] as p  
 INNER JOIN [tbl_person_languages] as pl 
    ON [p].[id] = [pl].[person_id])
 INNER JOIN [tbl_person_crossCuttingSkills] As ccp 
    ON [p].[id] = [ccp].[person_id]
WHERE  
   cint(pl.language_id) in (12,14) AND 
    cint(ccp.skill_id) in (55) 
GROUP BY  
   p.id,
   p.first_name, 
   p.last_name
HAVING 
    count(pl.language_id) =2 AND 
    count(ccp.skill_id) = 1

我想从tbl_person中提取记录,其中记录具有所有WHERE要求。例如:我想选择所有使用意大利语(ID 12)和西班牙语(ID 15)并且具有烹饪技巧(55)的用户。他们需要满足所有要求,而不仅仅是一个或多个要求。我假设这是你使用GROUP BY和HAVING的地方。随着HAVING:

  count(pl.language_id) =2

我使用count = 2,因为语言WHERE子句(12和14)中有两个选项

我用

 count(ccp.skill_id) = 1

因为WHERE子句中有一个值(55)。

这是正确的方法吗?由于某种原因,这不返回任何记录(我的数据库中有一条记录符合这些要求的人)。但是,如果我改变我的HAVING:

count(pl.language_id) =2 AND 
count(ccp.skill_id) = 2

工作正常。为什么是这样?我的假设是如何工作不正确还是还有其他事情发生?

1 个答案:

答案 0 :(得分:1)

记住count()的作用。 。 。它计算非NULL值。因此,您计算两个非NULL值,然后计数相同。

在SQL的大多数方言中,您可以通过执行以下操作来解决此问题:

HAVING count(distinct pl.language_id) = 2 AND count(distinct ccp.skill_id) = 1

但这在MS Access中不起作用,因为MS Access不支持COUNT(DISTINCT)

所以,你可能会更加冗长。在你的情况下:

HAVING SUM(iif(cint(pl.language_id) = 12, 1, 0)) > 0 AND
       SUM(iif(cint(pl.language_id) = 14, 1, 0)) > 0 AND
       SUM(iif(cint(ccp.skill_id) = 55, 1, 0)) > 0

对不起,这个HAVING条款并不简单。您可以切换到与ANSI功能更紧密对齐的另一个数据库(例如SQL Server Express)。