【问题标题】:How do I search for a value in a column and also get count of the column in a single SQL query如何在列中搜索值并在单个 SQL 查询中获取列的计数
【发布时间】:2018-07-20 02:26:19
【问题描述】:

我在 MySQL 5.7 中有一个如下结构的表:

CREATE TABLE `post_like` (
  `post_title_id` varchar(255) NOT NULL,
  `user_name` varchar(50) NOT NULL,
  PRIMARY KEY (`post_title_id`,`user_name`),
) ENGINE=InnoDB;

我有以下数据

post_title_id    user_name

new-story        mani27
new-story        manipal
some-story       manipal

我正在尝试获取特定故事的点赞数,以及特定用户是否喜欢函数likeStatus(user_name, post_title_id)中的故事@

假设 likeStatus(mani27, new-story) 会导致:

count    status
2        1

我现在正在使用以下查询,它可以正常工作:

SELECT COUNT(user_name) AS count,
COUNT(CASE WHEN `user_name` = ? THEN 1 ELSE null END) as status
FROM post_like WHERE post_title_id = ?

但这会对表中的所有行执行 case 函数,而不是搜索索引列 user_name。

我可以使用两个不同的查询来获取用户名喜欢帖子的计数和状态,但这需要更多的时间。那么,有没有一种优化的方式来获得这个输出呢?

【问题讨论】:

  • 您使用的是哪个 DBMS? SQL 只是一种语言。
  • @MBijen 我在本地环境中使用 MariaDB,但它将部署在 MySQL 5.7.17 中
  • 短:SUM(user_name = ?) 但是...你真的想要一个大于 1 的值作为“状态”吗?
  • 另见GROUP BY
  • 谢谢@RickJames。我已经更改了 SUM(user_name = ?) 并且不,我不希望状态值更大,但这是我能想到的最好的值。

标签: mysql sql database relational-database query-optimization


【解决方案1】:

我没有检查查询,但这应该会给您一个想法。尝试分组

SELECT COUNT(user_name) AS count,
COUNT(CASE WHEN `user_name` = ? THEN 1 ELSE null END) as status
FROM post_like GROUP BY post_title_id HAVING post_title_id=?

但这会在表中的所有行上执行 case 函数 而不是搜索索引列 user_name

当您根据 post_title_id= 分组,然后对其应用计数函数时,用户名的行搜索数可以减少到该组中的行

【讨论】:

  • 谢谢@nikhil,我终于用SELECT COUNT(user_name) AS count, SUM(user_name = ?) as status FROM post_like GROUP BY post_title_id HAVING post_title_id=? 似乎比1M 记录表上的两个查询要快
【解决方案2】:

CASE 中而不是WHERE 中添加您的条件,然后确保使用DISTINCT 以避免重复:

SELECT COUNT(DISTINCT user_name) AS count,
COUNT(CASE WHEN `user_name` = ? AND post_title_id = ? THEN 1 ELSE null END) as status
FROM post_like

【讨论】:

  • 在计数中,我会用 post_title_id 过滤它们,否则我会收到所有帖子组合的喜欢。因此,这会有帮助吗? SELECT COUNT(CASE WHEN post_title_id = ? THEN 1 ELSE null) AS count, COUNT(CASE WHEN user_name = ? AND post_title_id = ? THEN 1 ELSE null END) as status FROM post_like
【解决方案3】:

您不必扫描所有记录来查看用户是否喜欢该帖子。只需在选择列表上使用子查询。那应该使用主键索引。 像这样的东西应该可以工作

SELECT COUNT(*), 
    (SELECT COUNT(*) FROM post_like WHERE postid=? AND userid=?)
WHERE postid=? 

【讨论】:

  • 那不等于执行两个查询吗?
猜你喜欢
  • 1970-01-01
  • 2017-01-08
  • 2018-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
相关资源
最近更新 更多