【问题标题】:Add computed value as new column while also removing duplicates将计算值添加为新列,同时删除重复项
【发布时间】:2023-03-09 07:27:01
【问题描述】:

假设我有下表playgrounds

 serialnumber  length  breadth  country
 1             15      10       Brazil
 2             12      11       Chile
 3             14      10       Brazil
 4             14      10       Brazil

现在,我想在表中添加一列 area,本质上是 length*breadth

显然,我可以进行此更新:

UPDATE playground set area = length*breadth where country = 'Brazil'.

使用上述语句,我将不得不为序列号 3 和 4 计算两次不必要的长度 * 宽度。有没有办法添加 group by 并最大限度地减少计算量?

类似:

UPDATE playground set area = length*breadth where country = 'Brazil'
group by length, breadth;

【问题讨论】:

  • 有一些方法,如何只计算一次表达式,但是使用这些方法的计算成本必须相当高。简单的方法(重复评估)不需要随机 io - 你只需 seq 扫描。其他方法需要选择不同的值,计算,然后加入计算值。您的问题与错误的规范化有关 - 在设计良好的数据库上,您不需要解决类似的问题。

标签: postgresql group-by sql-update duplicates


【解决方案1】:

首先要注意的是,您不应将该区域添加为列。恰好是简单算术运算结果的数据项不需要自己的列。

第二点是您不必担心对第 3 行和第 4 行各执行一次乘法运算。这对服务器来说几乎是零工作

第三点是,如果你担心第 3 行和第 4 行,那就意味着它们是重复的,重复的数据不应该在数据库中。考虑按照此处所述删除重复项:https://wiki.postgresql.org/wiki/Deleting_duplicates

【讨论】:

  • 我了解数据重复。在我的场景中,我的表中有 40 多个列,并且我尝试计算的值在同一个表中使用了 5 个以上的列。这些列不直接使用,它们在内部进行一些计算/调节后使用。例如,我检查这 4 列之一中的特定字符串是否遵循特定的正则表达式模式并将其转换为整数,然后使用它与经过更多条件的另外 4 列相乘并计算结果。续。
  • 我知道我可以将 4 列分开并将结果放在单独的表中,但我觉得这样做真的是过度规范化。
【解决方案2】:

回答你的问题:

有没有办法,我可以添加分组并最小化计算量?

SELECT DISTINCT ON (1,2,3)
       length, breadth, country, length * breadth AS area
FROM   playgrounds
ORDER  BY 1, 2, 3, serialnumber;

这会从每组重复项中取出具有最小 serialnumber 的行。详细解释:

但首先考虑@e4c5's answerPavel's comment。不要存储可以廉价地即时计算的功能相关值。只需删除重复的行并使用view

永久删除具有更大serialnumber的欺骗:

DELETE FROM playgrounds p
WHERE  EXISTS (
   SELECT 1
   FROM   playgrounds
   WHERE  length  = p.length
          breadth = p.breadth
          country = p.country
   AND    serialnumber < p.serialnumber
   );

然后:

CREATE VIEW playgrounds_plus AS
SELECT *, length * breadth AS area
FROM   playgrounds;

相关:

【讨论】:

    猜你喜欢
    • 2015-02-28
    • 1970-01-01
    • 2020-03-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多