一直在挣扎,希望得到一些帮助 在轨道上运行了很多数学函数并找到了虚假的结果后,我决定爬下来在数据库中执行它,发现它对我来说都是非常可行的,但是当我到达第二个函数时以下错误:
PG :: UndefinedFunction:错误:函数updown(整数)不存在 第3行:SELECT" updown" (滞后(updown)结束(按id排序))table_nam ... ^提示:没有函数匹配给定的名称和参数类型。
迁移:
class CreateSmoothings < ActiveRecord::Migration
def change
create_table :smoothings do |t|
t.decimal :firstsmprice, :precision => 8, :scale => 6
t.decimal :finalsmprice, :precision => 8, :scale => 6
t.decimal :firstsmdelta, :precision => 8, :scale => 6
t.decimal :finalsmdelta, :precision => 8, :scale => 6
t.integer :updown, :null => false, :default => 0
t.integer :posture
t.integer :step
t.references :usdzar, index: true, foreign_key: true
t.references :smoothval, index: true, foreign_key: true
t.timestamps null: false
end
add_index :smoothings, :finalsmprice
end
end
我有一个更新控制器,用于设置来自另一个表的平滑数据,这是触发器触发的时间。第一个触发器就像一个魅力。这是控制器动作,然后是触发器和功能。
#POST / smoothings工作并将所有数据插入到平滑表
def create
# Do the 1st and 2nd SMOOTHINGS
# Get the row with the smoothval_id parameter to use these
sv = Smoothval.find(smoothing_params[:smoothval_id])
fval = sv.fval
sval = sv.sval
svid = sv.id
toremove = Smoothing.where(:smoothval_id => sv.id)
toremove.destroy_all
# For every entry in the table do:
collection = Usdzar.all
collection.each_with_index do |usdzar, i|
# Declare the previous variables required for id = 1 as
# the calculation cannot be done as it has no previous id
# I am sure this can be refactored
if usdzar.id == 1
prevprice = usdzar.price
prevfirstsmprice = usdzar.price
prevfinalsmprice = usdzar.price
else
prevprice = collection[i-1].price
prevfirstsmprice = Smoothing.last.firstsmprice
prevfinalsmprice = Smoothing.last.finalsmprice
end
# Do the smoothing calcs for the first smoothing using fval (first value)
firstsmprice = (((fval * usdzar.delta)/100) + prevprice)
# Find the difference of the current and previous of the first smoothing
firstsmdelta = firstsmprice - prevfirstsmprice
# Do the final smooting with the fval
finalsmprice = ((sval * firstsmdelta)/100) + prevfirstsmprice
# Find the differance of the current and previous of the second smoothing
finalsmdelta = finalsmprice - prevfinalsmprice
# Create the rows at end of iteration
Smoothing.create!(
usdzar_id: usdzar.id,
smoothval_id: sv.id,
firstsmprice: firstsmprice,
firstsmdelta: firstsmdelta,
finalsmprice: finalsmprice,
finalsmdelta: finalsmdelta
)
end
redirect_to smoothings_url, notice: 'Old smoothings removed and new smoothings successfully created.'
触发功能和触发器有效: - )
CREATE TRIGGER a_smoothings_trigger
AFTER INSERT
ON smoothings
FOR EACH ROW
EXECUTE PROCEDURE make_updowns_trg();
CREATE FUNCTION make_updowns_trg()
RETURNS trigger
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
update smoothings
set updown = case when (finalsmdelta < 0) then 1
when (finalsmdelta > 0 ) then 0
else 2 end;
RETURN NULL;
END
$BODY$;
这(上述)运行良好。 我接下来要做的是通过另一个触发器和函数扩展函数(现在知道它们按字母顺序运行 触发器/功能用于采取&#34; updown&#34; (0,1或2:向上,向下或相同是轨道中的枚举)和:
如果updown和next updown相同,则更新为2(中间) 如果updown大于next&#34; updown&#34;更新为1(高) 如果updown小于下一个&#34; updown&#34;更新为0(低)
CREATE FUNCTION public.make_high_lows_trg()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100.0
VOLATILE NOT LEAKPROOF
AS $BODY$
BEGIN
WITH next_updown AS
(SELECT updown (lag(updown) over (order by id)) table_name FROM smoothings
ORDER BY id DESC)
update smoothings
set posture = case when updown < next_updown then 1
when updown > next_updown then 0
else 2 end;
RETURN NULL;
END
$BODY$;
CREATE TRIGGER b_smoothings_trigger
AFTER INSERT
ON public.smoothings
FOR EACH ROW
EXECUTE PROCEDURE public.make_high_lows_trg();
控制器的模型:
class Smoothing < ActiveRecord::Base
enum updown: [:up, :down, :same]
enum posture: [:high, :low, :inbetween]
belongs_to :usdzar
belongs_to :smoothval
end
我把这一切都在控制器中运行,因为我的模型方法编码非常糟糕并且一切都在运行,但是在测试后发现数据非常不可靠。在此先感谢您的帮助。我对Postgres中的函数数量感到震惊,当我遇到窗口函数时认为它是合适的但可以克服障碍。我知道(来自psql文档)你不能把滞后/主导窗口放到函数的更新部分,但是显然有关于如何正确执行sql块的问题
此查询在运行第一个查询后运行,但如何更新表格:
with myUpdowns as (
Select id, updown, Lag(updown) over (order by id desc) next_updown from smoothings
)
select *
from myUpdowns
where updown < next_updown;
现在我得到了一个正确更新的高点:我现在正试图做到高点的全面传播。低和中间(0,1和2)。如果您有任何建议,我很乐意听到。向表中添加高位的更新触发器如下所示:
CREATE FUNCTION make_high_lows_trg()
RETURNS trigger
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
UPDATE smoothings
SET posture = 0
FROM (
Select id, updown, Lag(updown) over (order by id desc) next_updown from smoothings
) as highs
WHERE highs.updown < highs.next_updown
AND smoothings.id = highs.id;
RETURN NULL;
END
$BODY$;
触发器:
CREATE TRIGGER b_smoothings_trigger
AFTER INSERT
ON smoothings
FOR EACH ROW
EXECUTE PROCEDURE make_high_lows_trg();
嗯,现在如何做低和中间,实际上只是高低都很好