根据COUNT进行过滤

时间:2012-03-08 13:09:36

标签: sql sql-server sql-server-2008 tsql

我的查询效果非常好。但我正在尝试添加过滤器,以便users_in_this_country为> 1.我知道将users_in_this_country > 1添加到WHERE。但是,如果我在括号内添加它,则表示无效列,如果我将其添加到括号之外,则相同。这可能真的很愚蠢,但我在看什么呢?谢谢!

SELECT u.ContactName
      ,cu.[User ID]
      ,c.Name
      ,c.ID
      ,cu.[Foreign Table]
      ,count(*) OVER (PARTITION BY c.ID) AS user_in_this_country
FROM   dbo.Country AS c
INNER JOIN   dbo.CountryUser AS cu ON c.ID = cu.[Foreign ID]
INNER JOIN   dbo.UserColder  AS  u ON cu.[User ID] = u.ID
WHERE EXISTS (
    SELECT *
    FROM   CountryUser AS cu2
    WHERE  cu2.[Foreign ID] = cu.[Foreign ID]
    AND    cu2.[User ID] <> cu.[User ID]
    AND    cu.[Foreign Table] = 'Country')

3 个答案:

答案 0 :(得分:3)

你不能在WHERE子句中引用它的原因是它对给定行的意义取决于其他行满足WHERE子句的含义。所以这一切都太圆了。

最简单的解决方法是将整个查询包装在SELECT * FROM ( ... ) t WHERE t.user_in_this_country > 1

也就是说,您的查询已经确保user_in_this_country > 1凭借EXISTS子句确保存在不同的CountryUser Country }记录属于同一个User和另一个{{1}}。我错过了什么?

答案 1 :(得分:2)

使用与OVER子句一起使用的聚合函数(如COUNT),您必须使用CTE或子查询,如下所示

 WITH CTE AS (
      SELECT u.ContactName
          ,cu.[User ID]
          ,c.Name
          ,c.ID
          ,cu.[Foreign Table]
          ,count(*) OVER (PARTITION BY c.ID) AS user_in_this_country
      FROM   dbo.Country AS c
      INNER JOIN   dbo.CountryUser AS cu ON c.ID = cu.[Foreign ID]
      INNER JOIN   dbo.UserColder  AS  u ON cu.[User ID] = u.ID
      WHERE EXISTS (
          SELECT *
          FROM   CountryUser AS cu2
          WHERE  cu2.[Foreign ID] = cu.[Foreign ID]
          AND    cu2.[User ID] <> cu.[User ID]
          AND    cu.[Foreign Table] = 'Country')
 )
 SELECT *
 FROM CTE
 WHERE user_in_this_country > 1

答案 2 :(得分:0)

因为“users_in_this_country”不是列,所以它是在WHERE子句范围内无效的别名。我不熟悉“OVER”或PARTITION BY,但我猜你必须做这样的事情:

WHERE blabla AND (count(*) OVER (PARTITION BY c.ID)) > 1