Mysql跟踪用户喜欢和不喜欢的内容

时间:2010-11-26 00:27:46

标签: php mysql normalization

我正在创建一个公告板应用程序。每个公告都可以被网站的用户所喜欢或不喜欢。为了跟踪喜欢和不喜欢,我创建了以下数据库表

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 个答案:

答案 0 :(得分:6)

你可以使用聚合查询来执行此操作,在单个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

更新:根据以下评论中的讨论,喜欢/不喜欢的列可以归一化到自己的表中,就像这样(例如故意愚蠢......):

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')

然后,Bulletin表中的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 :(得分:1)

  1. 对于记录,还有另一种获取相同结果集的方法,无论是更快还是更慢取决于平台。这在外部查询上使用标量子查询而不是聚合。这个想法是,如果你考虑集合,这应该会更容易。或者就Dimension-Facts而言。

    首先,我们必须理顺你的名字。让我们调用你的“表格”bulletin_like和主要公告表bulletinbulletin_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. 您要求提供Normalization标记。 bulletin_like“表”未标准化。摆脱Id iot列,除了冗余列和附加索引之外,它没有用处。 PK是(bulletin_id, user_id)

    除非您希望用户在每个公告的每张海报上发布多个喜欢和不喜欢的内容。

答案 2 :(得分:0)

此查询对我有用:

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

这假设likesislike = 1表示“喜欢它”,喜欢喜欢= 0表示“不喜欢它”。

ID    LIKES    DISLIKES
1     2    1
2     0    1