Mysql отслеживать пользователей нравится и не нравится

Я создаю приложение на доске объявлений. Каждый бюллетень может понравиться или не понравиться пользователям сайта. Чтобы отслеживать симпатии и антипатии, я создал следующую таблицу базы данных.

id  user_id   bulletin_id   like_dislike
1   1         1             1
2   1         2             0
3   3         1             1
4   2         1             0

В столбце like_dislike 1 означает "Мне нравится", 0 означает "Не нравится", я знаю, как спросить. - Сколько раз бюллетень 1 понравился (2) - Сколько раз бюллетень 1 не понравился (1)

Но как мне сделать запрос, чтобы задать эти два вопроса одновременно? То есть сколько раз был бюллетень 1 понравился и не понравился

liked  disliked
2      1

Я пробовал запрос

  SELECT count(like_dislike) AS likes, count(like_dislike) AS dislikes FROM bulletins_ld
where bulletins_id = 1 AND likes = 1 AND dislikes = 0

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

3 ответа

Решение

Вы можете сделать это с помощью агрегированного запроса, используя противоположные условия в одном столбце like_dislike (ниже я предполагаю, что "1" в этом столбце означает "понравился").

SELECT bulletin_id, 
       SUM(CASE WHEN like_dislike = 1 THEN 1 ELSE 0 END) AS likes, 
       SUM(CASE WHEN like_dislike = 0 THEN 1 ELSE 0 END) AS dislikes
FROM bulletins_ld
GROUP BY bulletin_id

Обновление: согласно обсуждению в комментариях ниже, столбец like/dislike может быть нормализован в свою собственную таблицу, например так (пример намеренно глупый...):

CREATE TABLE how_user_feels(
    feeling_id INT,
    feeling_desc VARCHAR(20)
)

INSERT INTO how_user_feels(feeling_id, feeling_desc) VALUES
(0, 'Undecided'),
(1, 'Likes It'),
(2, 'Could Do Without It')

Столбец Likes_Dislikes в таблице бюллетеней затем заменяется внешним ключом feeling_idсо значением по умолчанию 0. Предположим, что вы вводите запись в эту таблицу, когда пользователь впервые просматривает бюллетень, по умолчанию делая его "Не определенным", и обновляете эту запись, когда голосуют в бюллетене. Вы можете запросить результаты так:

SELECT bulletin_id, 
       SUM(CASE WHEN feelings_id = 1 THEN 1 ELSE 0 END) AS likes, 
       SUM(CASE WHEN feelings_id = 2 THEN 1 ELSE 0 END) AS dislikes,
       SUM(CASE WHEN feelings_id = 0 THEN 1 ELSE 0 END) AS doesnt_seem_to_care
FROM bulletins_ld b
INNER JOIN how_user_feels h ON b.feeling_id = h.feeling_id
GROUP BY bulletin_id

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

  1. Для записи, есть другой способ получить тот же набор результатов, будь то быстрее или медленнее, зависит от платформы. Это использует скалярный подзапрос вместо агрегата во внешнем запросе. Идея в том, что это должно быть проще, если вы думаете с точки зрения множеств. Или с точки зрения измерения фактов.

    Сначала мы должны выяснить ваши имена. Давайте назовем ваш "стол" bulletin_like и основной бюллетень таблицы bulletin (bulletin_id это очень глупое имя для любого из них, это скорее название столбца). И просто вызвать логическую колонку like (если это 1, like правда; если это 0, like ложно; вот что значит логическое значение). Используйте единственную форму для имен.

    SELECT name AS bulletin, 
        (SELECT COUNT(like) 
            FROM  bulletin_like bl 
            WHERE bl.bulletin_id = b.bulletin_id 
            AND   like = 1
            ) AS like,
        (SELECT COUNT(like) 
            FROM  bulletin_like bl 
            WHERE bl.bulletin_id = b.bulletin_id 
            AND   like = 0
            ) AS dislike
    FROM bulletin b

  2. Вы попросили тег нормализации. Тот bulletin_like "таблица" не нормируется. Избавиться от Id В этом столбце он не служит никакой другой цели, кроме избыточного столбца и дополнительного индекса. ПК является (bulletin_id, user_id),

    Если вы не хотите, чтобы пользователи публиковали несколько лайков и дислайков за постер в бюллетене.

Этот запрос работал для меня:

SELECT bulletin_id, 
    sum(like_dislike) AS likes, 
    sum((1-like_dislike)) AS dislikes 
FROM bulletins_ld 
    GROUP BY (bulletin_id);

Предполагается, что likesislike = 1 означает "НРАВИТСЯ ЕГО", а likesislike = 0 означает "НЕ НРАВИТСЯ ЕГО".

ID    LIKES    DISLIKES
1     2    1
2     0    1
Другие вопросы по тегам