【问题标题】:Get a value from a table (using a criteria) and store in another table in one command从表中获取值(使用条件)并在一个命令中存储在另一个表中
【发布时间】:2019-06-26 09:21:31
【问题描述】:

我尝试使用满足另一个表中的条件的值的总和来更新表中的值。

在第一个命令中,我想获取共享文章的数量(这里是3):

db=# select article_id,liked,shared, COUNT(article_id) FROM social WHERE article_id > 0 GROUP BY article_id,liked,shared HAVING article_id=2087 AND shared=true;
 article_id | liked | shared | count 
------------+-------+--------+-------
       2087 | f     | t      |     3
(1 row)

我有另一个表,我需要把这个值 (3) 放在右栏中:

db=# SELECT article_id,shared FROM articles WHERE article_id=2087;
 article_id | shared 
------------+--------
       2087 |       
(1 row)

我可以在 Python 中使用两个命令来做到这一点,但我确信在一个 SQL 请求中有更好的方法来做到这一点?

编辑:

我试过这个命令:

db=# UPDATE articles SET shared=subquery.count FROM ( SELECT count(article_id) FROM social WHERE article_id=2087 AND shared=true) AS subquery WHERE article_id=2087;
UPDATE 1

db=# SELECT article_id,shared FROM articles WHERE article_id=2087;
 article_id | shared 
------------+--------
       2087 |      3
(1 row)

我只需要设置一次 article_id 就可以了。有什么建议吗?

【问题讨论】:

  • 把它变成一个答案。

标签: database postgresql dml


【解决方案1】:

我会将计数包装在 CTE 中并根据 CTE 的结果进行更新:

with counts as (
  select article_id,liked,shared, COUNT(article_id) as article_count
  FROM social
  WHERE article_id > 0
  GROUP BY article_id,liked,shared
  HAVING article_id=2087 AND shared=true
)
update articles a
set shared = c.article_count
from counts c
where a.article_id = c.article_id

其他一些挑剔的事情......

  1. HAVING article_id=2087 and shared=true 最好移至where 子句。当然,这会起作用,但HAVING 通常保留用于聚合函数(having count (*) > 1having sum (qty) = 0。将其移至 where 子句的好处是可以避免抓取和聚合最终被过滤掉的数据。我'不确定这一点,但它甚至可以更好地利用索引。

  2. shared=true 可以缩写为shared。你可能不喜欢不清楚这意味着什么,所以要么接受,要么放弃。

  3. 第一个查询与您要更新的内容不一致...具体而言,初始查询可能会返回多个结果,因为您不只是按 article_id 进行分组,因此您可能会得到很多结果同样的article_id。您相信这个构造会更新正确的构造。你是这个意思吗?

这三个建议的总结和一些假设:

with counts as (
  select article_id, COUNT(article_id) as article_count
  FROM social
  WHERE article_id > 0 and article_id=2087 AND shared
  GROUP BY article_id
)
update articles a
set shared = c.article_count
from counts c
where a.article_id = c.article_id

我知道article_id > 0article_id=2087 是多余的,但我认为后者是一个您最终会删除的测试用例,因此您可以一次更新所有记录。

【讨论】:

  • 非常感谢所有的解释!我从你的回答中学到了很多。是的,我需要按照您所说的进行分组,而 >0 仅用于测试。最终函数将在给定的特定“article_id”上触发,而不是针对所有 id。
  • 感谢您的反馈;我很高兴这很有帮助。有时人们只想要简短的答案,所以你永远不知道......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-31
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多