【问题标题】:Update a column with a COUNT of other fields is SQL?用其他字段的COUNT更新一列是SQL吗?
【发布时间】:2011-09-02 09:01:00
【问题描述】:

我设置了以下表格:

Articles:
ID | TITLE | CONTENT | USER | NUM_COMMENTS

COMMENTS
ID | ARTICLE_ID | TEXT

我需要一个 sql 语句来更新文章表的 NUM_Comments 字段,其中包含针对文章所做的 cmets 计数,例如:

update articles a, comments f 
set a.num_comments =  COUNT(f.`id`)
where f.article_id = a.id

上面的 sql 不起作用,我收到 Invalid Use fo Group 函数错误。我在这里使用 MySQL。

【问题讨论】:

  • 您究竟为什么要将这些信息存储在您的文章表中?您是否考虑过在每次需要该信息时计算 cmets?这样您就可以避免在数据库架构中出现重复的信息。
  • 文章表很大,我想避免进行连接,因为我还需要根据评论最多的方式对文章进行排序。
  • 好的,那么您的另一种选择是某种“物化视图”。

标签: mysql sql mysql-error-1111


【解决方案1】:

您不能在更新语句中加入。应该是

update articles
set num_comments =
(select count (*) from comments
where comments.article_id = articles.id)

这将更新整个文章表,这可能不是您想要的。如果您打算只更新一篇文章,请在子查询后添加“where”子句。

【讨论】:

  • 请注意,如果您为要更新的表设置别名,则可以加入更新 - 请参阅stackoverflow.com/questions/1293330/sql-update-with-join
  • 在每次评论插入时“制作”MySQL 的方法是什么(只是不重新计算所有内容,只增加)。我正在考虑使用附加查询在每次插入时增加 num_cmets 值,但这对我来说似乎很无聊。 MySQL 可以自己做吗?
  • 可以通过 cmets 表上的插入后触发器自动完成。但是还必须编写一个删除后触发器,以防评论被删除。不应该存储计数是有充分理由的!
  • “你不能在更新语句中加入”——这不是真的!您确实应该在更新操作需要时使用联接。
  • @sdlins:这取决于你的数据库系统。
【解决方案2】:

这应该可行。

UPDATE articles a SET num_comments = 
(SELECT COUNT(*) FROM comments c WHERE c.article_id = a.id)

但我宁愿在发表评论时只更新一条记录:

UPDATE articles a SET num_comments = 
(SELECT COUNT(*) FROM comments c WHERE c.article_id = 100) WHERE a.id = 100

【讨论】:

  • 我会每隔几个小时通过一个 cron 作业运行一次这个更新查询
【解决方案3】:

count (*) 可能有一些问题,尤其是 count 和 (*) 之间有空格...

所以在 sqlite 上运行 sql,pgsql 将是:

update articles 
  set num_comments = 
    (select count(id) from comments 
     where comments.article_id = articles.id)

【讨论】:

    【解决方案4】:

    要仅根据列数进行更新,您可以执行以下操作:

    update articles,
     (select count (*) 
      from comments
      where comments.article_id = articles.id) as newtotals
    set articles.num_comments = newtotals.count;
    

    或者...如果您遇到需要滚动计数的情况:

    update articles,
     (select (count (*)) + (articles.num_comments) as count 
      from comments
      join articles on 
        comments.article_id = articles.id
      group by articles.id) as newtotals
    set articles.num_comments = newtotals.count;
    

    【讨论】:

      【解决方案5】:

      您不能以通用的内部连接方式进行操作。但你可以通过其他方式做到这一点:

      1- 从文章表中选择所有 id

      2-迭代它们并执行以下命令

      更新文章集NUM_COMMENTS = (select count(id) from cmets where id = $id) where id = $id

      为了进一步增强它,在第一个选择中不要选择所有值,特别是当该表太大时,您需要迭代文章并每次迭代获得 1000 条记录。这样您就可以从您的数据库池中维护一个健康的数据库线程,并且还可以节省带宽。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-17
        • 1970-01-01
        • 2016-08-02
        • 1970-01-01
        • 1970-01-01
        • 2012-05-11
        • 1970-01-01
        • 2022-11-27
        相关资源
        最近更新 更多