给定具有列userIdarticleId的数据库表article_bookmarks,如果用户将一篇文章加入书签,则生成具有各自ID的表项(userIdarticleId).

我想检索的用户总数,书签的特定文章给articleId,连同信息,如果用户(给userId)也书签该文章.

我的SQL查询目前如下所示:

SELECT COUNT(ar.userId) AS bookmark_count,
       EXISTS(SELECT 1 FROM article_bookmarks WHERE articleId=:articleId AND userId=:userId) AS user_bookmarked
FROM article_bookmarks ar
WHERE ar.articleId=:articleId

我的印象是,这个查询并不是最优的,因为两次读出基本上相同的userId个数据似乎是低效和多余的:一次在"计数"中聚合,另一次由单个userId使用子 Select 进行过滤.

有没有一种方法可以优化或简化给定的SQL查询(如SELECT COUNT(ar.userId) AS bookmark_count, EXISTS(:userId IN ar.userId) AS user_bookmarked[...]在有效的SQL中)?

推荐答案

您可以使用条件聚合.这里,桌子article_bookmarks只被扫描一次.

SELECT 
    COUNT(ar.userId) AS bookmark_count,
    MAX(CASE WHEN userId=:userId THEN 1 ELSE 0 END) AS user_bookmarked
FROM article_bookmarks ar
WHERE ar.articleId=:articleId

为了避免扫描整个表,您需要在(articleId, userId)(articleId) include (userId)上建立索引.

Sql相关问答推荐

如何在SQL查询中只比较日期时间的年份和月份(而忽略日期比较)?

如何退回当年的所有参赛作品?""

SQL查询视图与连接?

Postgres:对包含数字的字符串列表进行排序

转换表中的数据

将主表与历史表连接以获取主表的当前汇率以及历史表中的上一个和最后一个汇率

分组多输出访问查询问题

UPDATE查询中的乐观锁

Redshift PL/pgSQL循环中的参数化列名

用VB.NET在Dapper中实现MS Access数据库顺序透视

如何使用聚合连接两个表

group by 并根据同表中其他列的某些条件获取 group by 中的某一列值

如何为给定的股票数据集计算利润/亏损,确保先卖出先买入的股票

PostgreSQL分割字符串为子词并判断其是否存在于其他字符串中

强制 SQL 始终通过 R 从视图中返回至少一行

如何在 DAX 中通过 Window 函数应用订单

如何 Select 一列具有最小值而另一列具有给定值的记录?

如何筛选 GROUP BY 结果? HAVING 没有产生预期的结果

SQL Server 查找存在于所有不同时期(或序列)中的条目

如何从 2 个 SQLite 表构建嵌套对象?