COUNT и GROUP BY в SQL Server - PullRequest
1 голос
/ 08 марта 2012

У меня есть этот запрос, и он выполняет пару соединений, но я хочу сделать Count, и теперь он дает счет 1 для всех. Что я делаю не так, чтобы сделать так, чтобы это на самом деле считается? Спасибо!

SELECT
  UserColder.ContactName,
  CountryUser.[User ID],
  COUNT(Country.Name) As num,
  Country.Name,
  Country.ID
FROM
  dbo.Country
  INNER JOIN dbo.CountryUser
    ON Country.ID = CountryUser.[Foreign ID]
  INNER JOIN dbo.UserColder
    ON CountryUser.[User ID] = UserColder.ID
WHERE
  EXISTS
  (SELECT
    NULL
   FROM
    CountryUser CU2
   WHERE
    CU2.[Foreign ID] = CountryUser.[Foreign ID]
    AND CU2.[User ID] <> CountryUser.[User ID])
    GROUP BY UserColder.ContactName, CountryUser.[User ID], Country.Name, Country.ID

EDIT:

Мои данные выглядят так:

Bob   United States
Tom   United States
Steve United Stated

Frank Canada
Billy Canada

Lou   China

Так что рядом с США должно быть 3 и Канада 2 и Китай 1.

Ответы [ 2 ]

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

Для подсчета пользователей в каждой стране оконная функция является одной из возможностей. Может выглядеть так:

SELECT u.ContactName
      ,cu.[User ID]
      ,c.Name
      ,c.ID
      ,count(*) OVER (PARTITION BY c.ID) AS users_in_this_country
FROM   dbo.Country     AS  c
JOIN   dbo.CountryUser AS cu ON c.ID = cu.[Foreign ID]
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])
    )

Я также использовал псевдонимы таблиц для сокращения синтаксиса (без изменений в функциональности) и удалил GROUP BY в подзапросе EXISTS, потому что он был без функции.


Как отфильтровать результат по оконной функции?

В ответ на комментарий: в вашем случае вы уже внедрили этот конкретный фильтр с предложением EXISTS.

Как правило, для фильтрации по результату оконной функции используйте подзапрос или CTE, например:

;With cte AS (
   < query from above >
   )
SELECT *
FROM   cte
WHERE  users_in_this_country > 1
0 голосов
/ 08 марта 2012

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

SELECT
  UserColder.ContactName,
  CountryUser.[User ID],
  (SELECT COUNT(C2.Name) FROM dbo.Country C2 INNER JOIN dbo.CountryUser CU2
    ON C2.ID = CU2.[Foreign ID]
    WHERE UserColder.ID = CU2.[User ID])  As num,
  Country.Name,
  Country.ID
FROM
  dbo.Country
  INNER JOIN dbo.CountryUser
    ON Country.ID = CountryUser.[Foreign ID]
  INNER JOIN dbo.UserColder
    ON CountryUser.[User ID] = UserColder.ID
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...