Фильтрация на основе COUNT - PullRequest
1 голос
/ 08 марта 2012

У меня есть запрос, который работает очень хорошо. Но я пытаюсь добавить фильтр, поэтому, если 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 ]

3 голосов
/ 08 марта 2012

Причина, по которой вы не можете обратиться к ней в предложении WHERE, заключается в том, что само ее значение для данной строки зависит от того, какие другие строки удовлетворяют предложению WHERE;так что все будет слишком круглым.

Самое простое решение - обернуть весь ваш запрос в SELECT * FROM ( ... ) t WHERE t.user_in_this_country > 1.

Тем не менее, ваш запрос уже гарантируетчто user_in_this_country > 1 в силу предложения EXISTS, которое гарантирует, что существует другая запись CountryUser, принадлежащая тому же Country и другому User.Чего мне не хватает?

2 голосов
/ 08 марта 2012

С агрегатными функциями (такими как COUNT), используемыми в сочетании с предложением OVER, вы должны использовать 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
0 голосов
/ 08 марта 2012

Поскольку "users_in_this_country" не является столбцом, это псевдоним, который недопустим в области действия предложения WHERE. Я не знаком с "OVER" или PARTITION BY, но, думаю, вам придется сделать что-то вроде этого:

WHERE blabla AND (count(*) OVER (PARTITION BY c.ID)) > 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...