首页 > 解决方案 > 您可以在 postgresql 的存储过程中的插入语句中的临时行上引用聚合函数吗?

问题描述

我正在编写一个 postgres 存储过程,它遍历从 select 语句返回的行。对于它循环通过的每一行,它将来自该 select 语句的值插入到一个新表中。我需要插入第二个表的值之一是一列的平均值。但是,当我调用存储过程时,我收到一个错误,即临时行没有我正在平均的实际列的属性。请参阅下面的存储过程和错误。

存储过程:

create or replace procedure sendToDataset(sentence int)
as $$
declare temprow peoplereviews%rowtype;
BEGIN

  FOR temprow IN
      select rulereviewid, avg(rulereview)
      from peoplereviews 
      where sentenceid = sentence
      group by rulereviewid
  loop
      insert into TrainingDataSet(sentenceId, sentence, ruleCorrectId, ruleCorrect, dateAdded)
          values(sentence, getSentenceFromID(sentence), tempRow.rulereviewid, tempRow.avg(rulereview), current_timestamp);
    END LOOP;

END
$$ 
LANGUAGE plpgsql;

错误:

ERROR:  column "rulereview" does not exist
LINE 2: ...omID(sentence), tempRow.rulereviewid, tempRow.avg(rulereview...
                                                             ^
QUERY:  insert into TrainingDataSet(sentenceId, sentence, ruleCorrectId, ruleCorrect, dateAdded)
          values(sentence, getSentenceFromID(sentence), tempRow.rulereviewid, tempRow.avg(rulereview), current_timestamp)
CONTEXT:  PL/pgSQL function sendtodataset(integer) line 11 at SQL statement
SQL state: 42703

基本上,我想知道是否可以在插入语句中使用该聚合函数,如果没有,是否有其他方法。

标签: postgresql-11

解决方案


您不需要为此使用缓慢且低效的循环:

 insert into TrainingDataSet(sentenceId, sentence, ruleCorrectId, ruleCorrect, dateAdded)
 select getSentenceId(sentence), sentence, rulereviewid, avg(rulereview), current_timestamp
 from peoplereviews 
 where sentenceid = sentence
 group by rulereviewid

要回答原始问题:您需要为聚合提供适当的别名:

  FOR temprow IN
      select rulereviewid, avg(rulereview) as avg_views
      from peoplereviews 
      where sentenceid = sentence
      group by rulereviewid
  loop
      insert into TrainingDataSet(sentenceId, sentence, ruleCorrectId, ruleCorrect, dateAdded)
      values(sentence, getSentenceFromID(sentence), tempRow.rulereviewid, 
             tempRow.avg_views, current_timestamp);
  END LOOP;

推荐阅读