【问题标题】:MySQL : Selecting count of mutiple enum valueMySQL:选择多个枚举值的计数
【发布时间】:2016-02-25 05:58:32
【问题描述】:

我正在制作一个电影评分应用程序,用户可以在其中将电影评分为“喜欢”或“不喜欢”。所以我做了3个表用户,电影和评级。投票表的例子是:

userID    movieID     Vote

 x        a           li
 y        a           dli
 y        b           li
 w        a           li

表的架构是:

userID - PrimaryKey
movieID - PrimaryKey
Vote - Enum('li','dli')

我已将 userID 和 movieID 作为主键,这样如果用户更新了他/她的偏好,那么如果记录存在,那么特定行也会更新。

编辑:这是电影表的架构。

mID - PrimaryKey
mName - Varchar
mGenre - Varchar
mDesc -  Text
mDateOfRelease - Date

我的问题是,是否可以从电影表中选择所有列,并在一次数据库调用中选择该电影的喜欢和不喜欢计数。如果是,我该怎么做?

【问题讨论】:

  • 你自己试过了吗?在建议之间,如果那里只有喜欢/不喜欢使用整数。
  • 你能把电影桌的布局也发一下吗?这将有助于组合一个示例 SQL 语句来执行此操作。
  • 使用 JOINS、GROUP BY、COUNT 等。不会那么难:)

标签: mysql enums


【解决方案1】:

假设您有电影,它包含字段id。以下是您可以执行的操作:

select m.*,sum(case when r.vote like 'li' then 1 else 0 end) likes,
sum(case when r.vote like 'dli' then 1 else 0 end) dislikes from movie m
left join rating r
on r.movieID = m.mID
group by m.mID;

左加入基本上是为了不投票。如果这部电影的分级表为空 - 它仍会显示它。

编辑: 为了解释这一点,我将删除此查询。

我们需要了解 group by 在做什么。你可以找到文档here。简而言之,我们会根据您的 group by 语句中列的不同条目创建数据组。

select count(r.movieID) from rating r
group by r.movieID;

这将为我们提供每部电影获得的票数(这里我们仅列出获得任何票的电影 - 评级表中的行)。所以在这之后我们可以做“智能”计数,并使用条件SUM function。在定义中你可以有一个表达式。这意味着case when ... then ... end 也可以工作。所以我们只是总结所有的“li”,不要用“dli”表示喜欢,用“dli”表示不喜欢。

唯一的一个大缺点是我们没有所有的电影(想想电影没有投票的情况)。然后这个选择将跳过这个。在这里我们有LEFT JOIN statement。这个想法很简单 - 我们包含 所有 表电影的行,无论评级表中发生了什么。 on 我们用来将这些连接到表格。然后我们回想一下我们之前所做的总结 but 将 group by 更改为 mID(它始终存在且非 null,因此我们总是有一些东西可以分组)。在这种情况下,您将拥有您想要的。也玩弄这个查询(结果一个)。尝试了解如果您将评分列留在分组语句中会发生什么。 (比阅读大量文字更容易看到:))

如果有什么不清楚的地方-请告诉我,我们会努力改进的。

希望对你有帮助

【讨论】:

  • 嗨,你能解释一下这里发生了什么吗?
  • 感谢您提供如此出色的解释...是的,我正在修改查询 :) 也将尝试加入用户表...如果我继续加入多个表会不会影响我的查询获取速度?
  • 好吧,如果你要进行全扫描(这意味着没有任何连接表达式,或者它是无用的表达式),它会给你带来糟糕的性能。不会导致您对表进行全面扫描的所有内容都可以。但是,有时需要全面扫描,所以 - 继续练习并使用表达式,它们会尽可能地指定你的行。
【解决方案2】:

试试这个:

select m.*, 
sum(case when v.vote = li then 1 else 0 end) li_count, 
sum(case when v.vote = dli then 1 else 0 end) dli_count
from movie m left join vote v on m.movieID = v.movieID 
group by m.mId (which is enough in mySQL)

【讨论】:

  • 嘿,它正在工作,谢谢......!你能解释一下我刚开始学习 MySql 发生了什么吗
  • 嗯,值得一提的是,在 Mysql 中,您不需要按所有 m 字段进行分组。 m.mId 就够了。
  • 是的,我们可以删除 (all cols in m) 部分
【解决方案3】:

试试这个:

SELECT 
    votes.movieID, 
    likes.like_count, 
    dislikes.dislike_count
FROM votes
LEFT join (
    SELECT movieID, count(Vote) as like_count
    FROM votes
    WHERE Vote = 'li'
    GROUP BY movieID
) likes ON likes.movieID = votes.movieID
LEFT join (
    SELECT movieID, count(Vote) as dislike_count
    FROM votes
    WHERE Vote = 'dli'
    GROUP BY movieID
) likes ON likes.movieID = votes.movieID

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    • 1970-01-01
    相关资源
    最近更新 更多