在WHERE / HAVING语句中使用COUNT()的SQL子查询

时间:2014-01-02 15:39:18

标签: sql sql-server count

考虑以下子查询。此查询检索拥有超过1'IDKleerkastPersoon'的员工的所有personalIds。对于此查询,我在 HAVING 条款中使用 COUNT ()语句。此subuqery返回员工的所有PersonalIds。

(SELECT     DISTINCT Persoon_1.Stamnr
 FROM          dbo.KleerkastPerPersoon AS KleerkastPerPersoon_1 INNER JOIN
                                               dbo.Persoon AS Persoon_1 ON KleerkastPerPersoon_1.ID_Persoon = Persoon_1.ID_Persoon
                        GROUP BY Persoon_1.Stamnr, Persoon_1.ID_Afdeling, KleerkastPerPersoon.IDKleerkastPersoon, Persoon.Naam
                        HAVING      (Persoon_1.ID_Afdeling = 2) AND (COUNT(KleerkastPerPersoon.IDKleerkastPersoon) >= 2)
                        ORDER BY Persoon_1.Stamnr DESC)

现在,用户只需要员工的PersonalId请求更多信息。所以我在它上面写了一个查询(见下文),它检索有关该员工的更多全局信息。正如所料,sql server拒绝这种方法。

SELECT     dbo.Persoon.Stamnr, dbo.Persoon.Naam, dbo.Persoon.Voornaam, dbo.Refter.RefterOmschrijving, dbo.Kleedkamer.KleedkamerOmschrijving, 
                  dbo.Kleerkast.KleerkastOmschrijving
FROM         dbo.KleerkastPerPersoon INNER JOIN
                  dbo.Persoon ON dbo.KleerkastPerPersoon.ID_Persoon = dbo.Persoon.ID_Persoon INNER JOIN
                  dbo.Kleerkast INNER JOIN
                  dbo.Kleedkamer ON dbo.Kleerkast.ID_Kleedkamer = dbo.Kleedkamer.ID_Kleedkamer INNER JOIN
                  dbo.Refter ON dbo.Kleedkamer.ID_Refter = dbo.Refter.ID_Refter ON dbo.KleerkastPerPersoon.ID_Kleerkast = dbo.Kleerkast.ID_Kleerkast
WHERE     (dbo.Persoon.Stamnr IN <<<Result of my first subquery>>>
                     )

抛出的错误消息是:

An aggregate may not appear in the where clause unless it is in a subquery contained in a having clause or a select list, and the column being aggregated is an outer reference

所以我将子查询移到了having子句:

<<<Query 2>>>
HAVING      (dbo.Persoon.Stamnr IN
                      (SELECT     TOP (100) PERCENT Persoon_1.Stamnr
                        FROM          dbo.KleerkastPerPersoon AS KleerkastPerPersoon_1     INNER JOIN
                                               dbo.Persoon AS Persoon_1 ON KleerkastPerPersoon_1.ID_Persoon = Persoon_1.ID_Persoon
                        GROUP BY Persoon_1.Stamnr, Persoon_1.ID_Afdeling
                        HAVING      (Persoon_1.ID_Afdeling = 2) AND (COUNT(KleerkastPerPersoon.IDKleerkastPersoon) >= 2)
                        ORDER BY Persoon_1.Stamnr DESC))

但是现在查询没有返回任何结果。虽然我应该看到98个不同的记录。你们有没有解决我的问题或我的解决方法?我怎样才能删除对子查询的需求。

3 个答案:

答案 0 :(得分:2)

将第一个子查询的结果存储在表变量中,然后在最终查询中使用它。除非您使用TOP。

,否则子查询中也不需要Order By子句

答案 1 :(得分:1)

好吧如果我得到你想要的东西,比如

SELECT dbo.Persoon.Stamnr, dbo.Persoon.Naam, dbo.Persoon.Voornaam, dbo.Refter.RefterOmschrijving, dbo.Kleedkamer.KleedkamerOmschrijving, dbo.Kleerkast.KleerkastOmschrijving
FROM dbo.KleerkastPerPersoon
inner join (your original query) SomeSuitableAlias
On SomeSuitableAlias.Stamnr = dbo.KleerkastPerPersoon.Stamnr 

应该做的。

答案 2 :(得分:0)

我认为错误消息中的聚合引用了第一个查询中的GROUP BY子句和COUNT(KleerkastPerPersoon.IDKleerkastPersoon)

当您将此选择用作子查询时,您显然引用的内容不是HAVING子句或SELECT语句的结果。您应该在子查询的结果集中包含所需的任何列或聚合。您还应该在子查询中保留ORDER BY部分(假设您还没有这样做)。

我无法确切地看到违规引用究竟是什么,但我同意mhasan的意见,至少在最初阶段,您应该通过使用一些临时表来解决您的查询,并且当您将其工作时将它们全部重新组合到一起一个查询。