将计算值添加为新列,同时删除重复项

时间:2016-07-27 19:05:37

标签: postgresql group-by sql-update duplicates

我们说我有下表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;

2 个答案:

答案 0 :(得分:2)

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

第二点是你不必担心第3行和第4行每次都要进行乘法运算。服务器的工作量几乎为零

第三点是,如果您担心第3行和第4行,这意味着它们是重复的,并且重复的数据不应该在数据库中。请考虑删除重复项,如下所述:https://wiki.postgresql.org/wiki/Deleting_duplicates

答案 1 :(得分: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

更大的dupes
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;

相关: