MySql выбирает значение по умолчанию, если результатов нет?

У меня есть 2 таблицы: участники и комментарии. Я выбираю всех участников, а затем присоединяюсь к комментариям. Но в комментариях я выбираю несколько СУММ точек, и если пользователь никогда не комментирует, я не могу получить этого пользователя в списке?!

Итак, как выбрать значение по умолчанию для SUM равным 0, если пользователь никогда не комментировал или какое-то другое решение:

SELECT c.comment_id AS item_id, m.member_id AS member_id, m.avatar, 
            SUM(c.vote_value) AS vote_value, SUM(c.best) AS best, 
            SUM(c.vote_value) + SUM(c.best)*10 AS total
            FROM members m
            LEFT JOIN comments c ON m.member_id = c.author_id
            GROUP BY c.author_id
            ORDER BY m.member_id DESC
            LIMIT 0, 20

EDIT:

Я попытаюсь объяснить... Таким образом, есть 2 таблицы, участники и комментарии. Мне нужен список всех пользователей с рейтингом. Комментарии содержат все голоса и лучшие ответы.

Итак, мне нужен список всех пользователей, и они оценивают.

Таблица участников:

member_id - username - avatar

Таблица комментариев

comment_id - author_id - vote_value - best (0 OR 1)

Также попытался выбрать из КОММЕНТАРИИ и присоединиться к ЧЛЕНАМ, но опять же: (

Ответ 1

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

SELECT
    M.member_id,
    M.user_id,
    M.avatar,
    COALESCE(SUM(C.vote_value), 0) AS vote_value_sum,
    COALESCE(SUM(C.best), 0) AS best_sum,
    COALESCE(SUM(C.vote_value), 0) + SUM(C.best) * 10 AS total_value
FROM
    Members M
LEFT OUTER JOIN Comments C ON
    C.author_id = M.member_id
GROUP BY
    M.member_id
ORDER BY
    total_value DESC
LIMIT 0, 20

(это предполагает, что vote_value и best являются NOT NULL столбцами или что MySQL будет игнорировать их при вычислении значений SUM - я считаю, что это так, но я не тестировал это)

Ответ 2

MySQL имеет оператор IFNULL, который позволяет вам вернуть значение, отличное от нуля, если результат равен нулю.

SELECT c.comment_id AS item_id, m.member_id AS member_id, m.avatar, 
            SUM(IFNULL(c.vote_value, 0)) AS vote_value, SUM(IFNULL(c.best, 0)) AS best, 
            SUM(IFNULL(c.vote_value, 0)) + SUM(IFNULL(c.best, 0))*10 AS total
            FROM members m
            LEFT JOIN comments c ON m.member_id = c.author_id
            GROUP BY c.author_id
            ORDER BY m.member_id DESC
            LIMIT 0, 20

Как упоминалось выше, COALESCE делает что-то подобное (а также работает в MySQL).

Ответ 4

Я не думаю, что проблема SUM - проблема. Я думаю, это может быть ваш

GROUP BY c.author_id

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

Сказав это, да, вы также должны использовать COALESCE или IFNULL для преобразования нулевых значений в 0.

Ответ 5

Вы можете использовать оператор if для преобразования NULL в 0

SELECT c.comment_id AS item_id, ...
    IF(SUM(c.vote_value) is null, 0, SUM(c.vote_value)) as vote_value
FROM members m
LEFT JOIN comments c ON ...

Ответ 6

Вы также можете взглянуть на выражение CASE: http://dev.mysql.com/doc/refman/5.0/en/case-statement.html

В вашем случае результат будет похож на...

SELECT c.comment_id AS item_id, m.member_id AS member_id, m.avatar, 
        (CASE SUM(c.vote_value) WHEN NULL THEN 0  
        ELSE SUM(c.vote_value) END) AS vote_value, SUM(c.best) AS best, 
        (CASE SUM(c.vote_value) + SUM(c.najbolji)*10 WHEN null THEN 0
        ELSE SUM(c.vote_value) + SUM(c.najbolji)*10 END) AS total
        FROM members m
        LEFT JOIN comments c ON m.member_id = c.author_id
        GROUP BY c.author_id
        ORDER BY m.member_id DESC
        LIMIT 0, 20