Можете ли вы сослаться на агрегатную функцию во временной строке в операторе вставки в хранимой процедуре в 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

По сути, мне интересно, можно ли использовать эту агрегатную функцию в операторе вставки или нет, а если нет, то есть ли другой способ обойти это.


person DaynaE    schedule 15.11.2019    source источник
comment
Вы уверены, что значения перечислены в правильном порядке? Учитывая имена целевых столбцов, я бы предположил, что это должно быть values(getsentenceid(sentence), sentence, ...   -  person a_horse_with_no_name    schedule 15.11.2019
comment
Да, потому что предложение представляет идентификатор предложения (postgres не позволил бы мне использовать идентификатор предложения в качестве имени параметра, потому что он сказал, что оно неоднозначно), а getentencefromID(предложение) получает фактическое предложение с учетом идентификатора предложения.   -  person DaynaE    schedule 18.11.2019


Ответы (1)


вам не нужно использовать для этого медленный и неэффективный цикл:

 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;
person a_horse_with_no_name    schedule 15.11.2019
comment
Ваше первое предложение сработало отлично! Я пытался сделать то, что вы предложили во второй части вашего ответа, однако, когда я пытался использовать псевдоним, я получал сообщение об ошибке, говорящее, что у temprow нет атрибута rulereviewid или любого другого атрибута, на который я пытался ссылаться. - person DaynaE; 18.11.2019