我有一个查询,它使用聚合函数将maximum absolute
值分配给表中的另一列。问题是它需要花费大量时间(apprx。加上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 :(得分:2)
我确实设法修改了查询,结果嵌套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);
答案 1 :(得分: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不会以这种方式实现它,但很可能,性能应该比图片所表明的要好得多。答案 2 :(得分: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 )
答案 3 :(得分:0)
我希望下面的sql对你有所帮助,我在netezza中测试过,但不是postgresql。另外,我没有把更新放在它上面。
SELECT ABS(COM.TP)
从TC C LEFT OUTER JOIN
(SELECT ID,TP
来自TS A.
什么不存在(选择1
来自TS B.
在哪里A.ID = B.ID
和ABS(B.TP)> ABS(A.TP)))COM
ON C.ID = COM.ID