Оставленные объединения -> проблема агрегатной функции - PullRequest
0 голосов
/ 21 сентября 2011

У меня в базе данных четыре разных таблицы:

нить:

  • нить_id
  • нить_контента
  • метка времени

Рейтинг темы:

  • идентификатор темы
  • идентификатор темы
  • нравится
  • не нравится

thread_report:

  • thread_report_id
  • thread_id

thread_impression:

  • thread_impression_id
  • thread_id

И я собираюсь присоединиться к этим таблицам с помощью этого SQL-запроса

SELECT t.thread_id,
t.thread_content,
SUM(tra.liked) AS liked,
SUM(tra.disliked) AS disliked,
t.timestamp,
((100*(tra.liked + SUM(tra.liked))) / (tra.liked + SUM(tra.liked) + (tra.disliked + SUM(tra.disliked)))) AS liked_percent,
((100*(COUNT(DISTINCT tre.thread_report_id)) / ((COUNT(DISTINCT ti.thread_impression_id))))) AS reported_percent
FROM thread AS t
LEFT JOIN thread_rating AS tra ON t.thread_id = tra.thread_id
LEFT JOIN thread_report AS tre ON tra.thread_id = tre.thread_id
LEFT JOIN thread_impression AS ti ON tre.thread_id = ti.thread_id
GROUP BY t.thread_id
ORDER BY liked_percent

Запрос должен возвращать все thread_ids с вычисленными значениями «Нравится» и «Не нравится», «Нравится» в процентах, отметкой времени, когда поток был вставлен в базу данных, а отчеты - в процентах к показам (время, когда поток показывался пользователю)..

Почти все результаты верны, единственные результаты, которые не верны, - это лайки и антипатии.

Если яЯ вижу, что перед запросом имеется счетчик (*), в правильных результатах счетчик равен 1, а в неправильных - до 60. Кажется, что есть проблемы с перекрестным объединением ...

Я думаю, что это проблема с группировкой, или, может быть, мне следует объединить.

Я видел решения с подвыборками.Но я не думаю, что это отличное решение для этой проблемы ...

Что я здесь не так делаю?

1 Ответ

2 голосов
/ 21 сентября 2011

В таблице tra имеется несколько записей на каждый идентификатор_потока. Это вызвало двойной счет в функции SUM.
Выполните суммирование в подвыборах, сгруппированных по полю соединения.
Таким образом, у вас будет только один идентификатор_потока в tra2, и дублирующиеся строки будут исключены.

SELECT t.thread_id,
  t.thread_content,
  tra2.liked
  tra2.disliked,
  t.timestamp,
  tra2.liked_percent,
  ((100*(COUNT(DISTINCT tre.thread_report_id)) / ((COUNT(DISTINCT ti.thread_impression_id))))) AS reported_percent
FROM thread AS t
LEFT JOIN (
     SELECT 
       tra.thread_id 
       , SUM(tra.liked) AS liked
       , SUM(tra.disliked) AS disliked
       , ((100*(tra.liked + SUM(tra.liked))) / (tra.liked + SUM(tra.liked) + (tra.disliked + SUM(tra.disliked)))) AS liked_percent 
     FROM thread_rating AS tra
     GROUP BY tra.thread_id
) as tra2 ON t.thread_id = tra2.thread_id
LEFT JOIN thread_report AS tre ON tra.thread_id = tre.thread_id
LEFT JOIN thread_impression AS ti ON tre.thread_id = ti.thread_id
GROUP BY t.thread_id
ORDER BY liked_percent DESC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...