2016-06-28 135 views
2

我有一个查询使用聚合函数将maximum absolute的值分配给表中的另一列。问题是需要很长时间(约10-15秒)来查询完成时间。这是查询的样子:聚合到'普通'查询

UPDATE calculated_table c 
    SET tp = (SELECT MAX(ABS(s.tp)) 
       FROM ts s INNER JOIN tc t ON s.id = t.id 
       GROUP BY s.id); 

其中id不是唯一的,因此是分组。 tp是一个数字整数字段。下面是表的样子:

TABLE ts 
     PID(primary)  |   id (FKEY)    |      tp (integer)     
--------------------+-----------------------------+------------------------------------------------------ 
1      | 2        | -100 
2      | 2        | -500 
3      | 2        | -1000 

TABLE tc 
     PID(primary)  |   id (FKEY)        
--------------------+-----------------------------+------------------------- 
1      | 2        

我希望输出的样子:

TABLE c 
     PID(primary)  |   tp (integer)     
--------------------+-----------------------------+-------- 
1      | 1000         

我试图使它像这样的工作:

UPDATE calculated_table c 
    SET tp = (SELECT s.tp 
       FROM ts s INNER JOIN tc t ON s.id = t.id 
       ORDER BY s.tp DESC 
       LIMIT 1); 

虽然提高了性能,但结果是不正确的..任何帮助将不胜感激?

+0

可以TP是一个正的值Δα –

+0

你有没有适当的ID ID和TC ID? – scaisEdge

+0

@MaheshMadushanka是..我有ID的 – faizanjehangir

回答

2

我还是设法修改查询创建一个多列索引,turnsout嵌套aggregate functions是不是一个好的选择。但是,如果它可以帮助任何人,这里是我落得这样做:

UPDATE calculated_table c 
    SET tp = (SELECT ABS(s.trade_position) 
       FROM ts s INNER JOIN tc t ON s.id = t.id 
       WHERE c.id = s.id 
       ORDER BY ABS(s.tp) DESC 
       LIMIT 1); 
0

尝试:

UPDATE calculated_table c 
    SET tp = (SELECT greatest(MAX(s.tp) , - MIN(s.tp)) 
       FROM ts s INNER JOIN tc t ON s.id = t.id 
       WHERE c.id = s.id 
      ); 

也尝试在ts(id, tp)

0

我希望下面的SQL将会对您有所帮助,我在Netezza公司进行测试,而不是PostgreSQL的。另外,我没有把它更新。

SELECT ABS(COM.TP) FROM TC C向左OUTER JOIN
(SELECT ID,TP FROM TS甲 WHERE NOT EXISTS(SELECT 1 FROM TS乙 WHERE A.ID = B.ID 和ABS(B.TP)> ABS(A.TP)))COM ON C.ID = COM.ID

1

虽然它提高了性能,但结果却不正确。

手术很成功,但病人死亡。

与您的查询的问题是,

SELECT MAX(ABS(s.tp)) 
    FROM ts s INNER JOIN tc t ON s.id = t.id 
    GROUP BY s.id); 

不会产生一个标值;它会生成一个值为的列,每个值为s.id。你的DBMS真的应该引发一个语法错误。就性能而言,我认为您将按顺序将子查询生成的每行应用于目标表中的每一行。这可能既缓慢又错误。

您想要的是将您的select输出与您正在更新的表相关联,并将行更新为相关的行。下面是从另一个表更新一个表的ANSI语法:

UPDATE calculated_table 
SET tp = (SELECT MAX(ABS(s.tp)) 
      FROM ts s INNER JOIN tc t ON s.id = t.id 
      where s.id = calculated_table.id) 
where exists (select 1 from ts join tc 
       on ts.id = tc.id 
       where ts.id = calculated_table.id) 

这应该接近你想要的。

顺便说一句,它很容易从字面上理解相关的子查询,认为子查询是运行N次,对于目标表中的每一行。这是正确的方式来描绘它,逻辑。 DBMS不会以这种方式实现,但很可能,性能应该比图片所显示的要好得多。