СУММА SQL с CASE и DISTINCT? - PullRequest
       4

СУММА SQL с CASE и DISTINCT?

3 голосов
/ 14 октября 2010

Продолжая мой последний вопрос ...

Позвольте мне попытаться объяснить мою схему.У меня есть три таблицы, которые мы будем называть пользователями (с идентификаторами и именами столбцов), сторонами (с идентификаторами столбцов, partydate и user_id) и вопросами (с идентификаторами столбцов, createate и user_id).Мое требование - показать каждому пользователю количество сторон за последний год и вопросы, созданные за последний год.

Мой запрос выглядит так:

SELECT users.id, users.name,  
  SUM(CASE WHEN (parties.party> NOW() - interval '1 year') THEN 1 ELSE 0 END) 
    AS numparties, 
  SUM(CASE WHEN (questions.createdate> NOW() - interval '1 year') THEN 1 ELSE 0 END)
    AS numquestions
FROM users
  LEFT JOIN parties ON users.id=parties.user_id
  LEFT JOIN questions ON users.id=questions.user_id
GROUP BY users.id, users.name;

Это работает почти на 100%.Я получаю результат со всеми пользователями, которые существуют.Проблема в том, что для некоторых пользователей (очень маленьких) я считаю партию или вопрос дважды.Например, если я изменю приведенный выше запрос, чтобы вместо того, чтобы суммировать их, а также удалял GROUP BY, вместо того, чтобы суммировать их, а вместо этого выводил GROUP BY, я мог получить что-то вроде:

user.id | user.name | parties.id | questions.id  
-----------------------------------------------
0          John          15             2
0          John          15             7

Вы можете увидеть этопоказывает сторон.ид дважды.

Когда я использовал COUNT (), я мог положиться на DISTINCT, но с SUM я не уверен, как я могу.Я хочу что-то вроде:

SUM(CASE WHEN (parties.party> NOW() - interval '1 year' AND parties.id IS DISTINCT) THEN 1 ELSE 0 END) 
AS numparties, 

Но, конечно, это не верно.Можно ли легко исправить эту небольшую проблему?

Ответы [ 2 ]

3 голосов
/ 14 октября 2010

Я не буду писать код для вас (так как это домашняя работа), но вы захотите поместить два вычисления в подзапросы.

Вот шаблон:

  SELECT users.id, users.name, 
         subquery1.result_of_calculation1, subquery2.result_of_calculation2
    FROM users
         LEFT JOIN (
            --calculation 1
         ) subquery1
         ON users.id = subquery1.user_id
         LEFT JOIN (
            --calculation 2
         ) subquery2
         ON users.id = subquery2.user_id
GROUP BY users.id, users.name;
0 голосов
/ 14 октября 2010

Следуя совету Адама, я пришел к следующему:

SELECT users.id, users.name, 
  COALESCE(tparties.ecount,0),
  COALESCE(tquestions.pcount,0)
FROM users
  FULL JOIN (
    SELECT user_id,COUNT(parties.id) AS ecount 
    FROM parties 
    JOIN users ON parties.user_id = users.id 
      AND parties.partydate > NOW() - interval '1 year' 
    GROUP BY user_id) 
    as tparties ON users.id=tparties.user_id
  FULL JOIN (
    SELECT user_id,COUNT(questions.id) AS pcount 
    FROM questions JOIN users ON questions.user_id = users.id 
      AND questions.createdate > NOW() - interval '1 year' 
    GROUP BY user_id) 
    as tquestions ON users.id=tquestions.user_id
;

Хорошая новость заключается в том, что все пользователи перечислены и все подсчеты верны.Плохая новость заключается в том, что он упорядочил дату по user_id, тогда как результат, который дал учитель для проверки наших запросов, выглядит неупорядоченным.Я понимаю, что вышеприведенный запрос не является ответом, который ищет учитель.Тем не менее, результат тот же, и, учитывая количество времени, которое я потратил на одну проблему, мне этого вполне достаточно.Спасибо за помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...