У меня есть две таблицы в моем проекте, которые мне нужно соединить несколько сложным образом, и это вызывает у меня очень странные проблемы.
У меня есть концепция команд и концепция FeedItems. FeedItems означает, что команда решила задачу. Мне нужно знать, когда они в последний раз решали задачу, и мне также нужно вычислить сумму элементов FeedItem на основе точек.
SELECT COALESCE(sum(challenges.point_value), 0) + COALESCE(sum(point_feed_items.point_value), 0) as team_score,
GREATEST(MAX(pentest_feed_items.created_at), MAX(point_feed_items.created_at)) as last_solve_time, teams.* FROM "teams"
LEFT JOIN feed_items AS point_feed_items
ON point_feed_items.team_id = teams.id
AND point_feed_items.type IN ('StandardSolvedChallenge', 'ScoreAdjustment')
LEFT JOIN feed_items AS pentest_feed_items
ON pentest_feed_items.team_id = teams.id
AND pentest_feed_items.type IN ('PentestSolvedChallenge')
LEFT JOIN challenges ON challenges.id = point_feed_items.challenge_id
AND challenges.type IN ('StandardChallenge') WHERE "teams"."division_id" = $1
GROUP BY teams.id ORDER BY "teams"."created_at" ASC
Это работает почти всегда, я просто сталкиваюсь с краем случай, когда я иногда получаю то же самое ScoreAdjustment в сумме point_feed_items.point_value. Я позвонил по номеру COUNT(point_feed_items.point_value)
и подтвердил, что мне каким-то образом возвращаются 3 элемента, хотя их должно быть только 1. Я до сих пор не мог понять, почему один и тот же элемент иногда возвращается несколько раз, или как вызвать DISTINCT как часть LEFT JOIN, чтобы полностью избежать проблемы.
Я обнаружил, что удаление 2-го LEFT JOIN устранило проблему, однако мне нужны данные из этого LEFT JOIN. задать другой способ, я заменил COALESCE(sum(point_feed_items.point_value), 0)
на COALESCE(COUNT(point_feed_items.point_value), 0)
и проверил без корректировки ScoreAdjustments в базе данных, которую он возвратил 0. Затем я создал одно ScoreAdjustment с правильной командой и COALESCE(COUNT(point_feed_items.point_value), 0)
затем вернул 3 вместо 1. Я неправильно понимаю, как LEFT JOIN AS работает?
Это часть приложения rails, однако в основном оно написано как ручной запрос для повышения производительности.