Расчеты в связанных таблицах

Изображение Mrgreenm

Здравствуйте!
Требуется помощь! Я начинающий пользователь Postgre и имею ,еще пока, очень смутное представление о механизмах работы баз данных и совсем неуверенно пишу на языке SQL. Имеются две таблицы: Таблица полей POLY (поле например картофельное) и таблица элементарных участков EU на которые эти поля разбиты. Таблицы связаны по номеру поля FLD_ID! Т.е. если поле №1 разбито на 3 элементарных участка, то в таблице POLY одна строчка №1 (FLD_ID=1) а в таблице EU 3 строчки с №1 в столбце FLD_ID. В таблице EU содержится комплексная информация по элементарному участку, например содержание фосфора, калия, магния в почве!
Задача: заполнить таблицу полей POLY из суммы элементарных участков данного поля таблицы элементарных участков EU, т.е например сложить все строки где FLD_ID = 1 например по фосфору таблицы EU и записать полученное значение в Таблицу полей POLY в колонку фосфора первому полю (FLD_ID=1)

Задача вроде не сложная, но я не могу представить как это делается, помогите пожалуйста!

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Нет, безусловно, готовый

Нет, безусловно, готовый рецепт я вам дать могу и это даже нетрудно.
Однако, тогда вы ничему не научитесь.
Попробуйте почитать литературу
http://postgresql.ru.net/docs/sql_kg/index.html
Подсказка, вам нужны агрегатные функции для обсчёта
http://postgresql.ru.net/docs/sql_kg/2-5-1.html
После того как научитесь выводить нужные данные на экран, всё что останется сделать для заполнения таблицы POLY - это

DROP TABLE POLY;
CREATE TABLE POLY AS SELECT .... и вот тут ваш запрос будет

Спасибо за наводку!!!! Буду

Изображение Mrgreenm

Спасибо за наводку!!!! Буду копать!!

Забыл уточнить, что моя база

Изображение Mrgreenm

Забыл уточнить, что моя база является базой геоданных, т.е. таблица является атрибутивной информацией импортированного шейпфайла и содержит ряд других данных! У меня есть подозрение, что запрос типа DROP TABLE POLY удаляет таблицу, а это, с точки зрения моей неопытности, может привести к потере данных, ранее содержащихся в таблице, и наверно потере связи с геоданными! Так ли это?

Наметки таковы:

SELECT sum(фосфор) FROM "eu" WHERE FLD_ID=1 - суммируем весь фосфор первого поля в таблице эллементарных участков EU

получившееся значение надо занести в таблицу полей "poly" в столбец "Сумма фосфора" строку where FLD_ID=1; (не могу грамотно написать команду insert для данной операции)
и такой расчет необходимо провести для каждого поля, т.е. для всех значений FLD_ID!
Исходя из опыта программирования на паскале я бы создал цикл со щетчиком FLD_ID от 1 до i и прогнал бы циклом! Возможен ли на SQL такой вариант?

И если можно напишите готовое решение!
Я бы с удовольствием разобрался сам (чем я потихоньку и занимаюсь) просто сроки горят и нет времени на изучение, приходится разбираться по ходу!
Буду очень признателен и бесконечно благодарен!!!

Если у вас в таблице есть

Если у вас в таблице есть другие данные, которые не генерируются динамически, тогда конечно DROP делать на таблицу не надо.

UPDATE poly SET sumfosfor=(SELECT sum(фосфор) FROM "eu" WHERE FLD_ID=1) WHERE FLD_ID=1;

Не очень красиво, но должно работать для каждой конкретной строчки таблицы
А вообще лучше создать триггер на таблицу eu для действий INSERT, DELETE, UPDATE и по этому триггеру выполнять данный выше запрос.

Готовое решение я вам написать не могу - у меня на руках нет точных структур ваших таблиц.

Спасибо!!!!Запрос работает

Изображение Mrgreenm

Спасибо!!!!
Запрос работает как часы!!!

Тригер это конечно здорово, но я так понимаю что тригер срабатывает когда производится какое то действие с таблицей, скажем если я сделаю тригер на таблицу EU на заполнение фосфора то после ввода оператором значения фосфора в каждую ячейку таблицы, будет запускаться тригер который автоматом, по вышеупомянутому запросу, просчитает сумму для текущего значения FLD_ID. Но беда в том что таблица уже заполнена и как таковых действий типа INSERT, DELETE, UPDATE таблица EU уже не требует, осталось только по ней просчитать ряд столбцов таблицы POLY!

сейчас эксперимента ради сделал следующее

UPDATE poly SET sumfosfor=(SELECT sum(фосфор) FROM "eu" WHERE FLD_ID=1) WHERE FLD_ID=1;
UPDATE poly SET sumfosfor=(SELECT sum(фосфор) FROM "eu" WHERE FLD_ID=2) WHERE FLD_ID=2;
UPDATE poly SET sumfosfor=(SELECT sum(фосфор) FROM "eu" WHERE FLD_ID=3) WHERE FLD_ID=3;
UPDATE poly SET sumfosfor=(SELECT sum(фосфор) FROM "eu" WHERE FLD_ID="И ТАК далее") WHERE FLD_ID="И ТАК далее";

безумно глупое решение, но оно работает)))
Пробовал создать цикл типа

declare
  var int;
begin
FOR var IN 1 ON (SELECT max(FLD_ID) FROM "POLY")
loop
 UPDATE poly SET sumfosfor=(SELECT sum(фосфор) FROM "eu" WHERE FLD_ID=var) WHERE FLD_ID=var;
end loop;
end;

Но такой запрос срызу выкидывает
ERROR: syntax error at or near "int"
LINE 87: var int;
^
Подскажите пожалуйста что можно с этим сделать!!!

Почему у вас declare вне

Почему у вас declare вне функции? Вне функции - это работа с курсором. Судя по тексту вы хотите PL/pgSQL, тогда вам прямая дорога к изучению этой главы:
http://postgresql.ru.net/manual/plpgsql.html
кроме того int является зарезервированным словом.
Поэтому тогда бы уже задекларировали переменную, присвоили ей результат SELECT'а, а уже потом бы переменную ставили в FOR, мне кажется должно прокатить без проблем.

Спасибо большое за помощь,

Изображение Mrgreenm

Спасибо большое за помощь, написал функцию, все заработало!
Единственно проблема оказалась чтобы эту функцию вызвать!
взгляните пожалуйста на код и посоветуйте как его подправить в более правильный и приглядный вид

DROP FUNCTION raschet();
CREATE OR REPLACE FUNCTION raschet() RETURNS integer AS $$ --Создается функция расчета
DECLARE			--Объявляются переменные
    schet integer;	--Переменная счетчика
    oppa1 integer;	--Переменная возврата функции
BEGIN
schet:= (SELECT max(FLD_ID) FROM "ALT_RBR_imlenina10_poly"); -- Присваевается значение максимального FLP_ID
FOR oppa IN 1..schet
loop
SELECT fld_id FROM "ALT_RBR_imlenina10_poly" INTO oppa1 WHERE fld_id=oppa; -- Для возврата функции (незнаю зачем но без этого не работало)
UPDATE "ALT_RBR_imlenina10_poly" SET av_p_p <img class="ccfilter smileys" src="https://pgdocs.ru/sites/all/modules/ccfilter/smileys/ac.gif" alt="=(" title="=(" />select sum(p) / count(p) FROM "ALT_RBR_imlenina10_eu" WHERE FLD_ID=oppa) WHERE FLD_ID=oppa; -- Вычисляется среднее значение и заносится в таблицу Poly
end loop;
RETURN oppa 1; --(незнаю зачем но без этого не работало)
END;
$$ LANGUAGE plpgsql;
SELECT fld_id FROM "ALT_RBR_imlenina10_poly" WHERE FLD_ID=raschet(); -- Для вызова функции (сделано по интуиции но сработало)

Если работает, то зачем

Если работает, то зачем править?
Вызывают функцию через SELECT имя_функции(параметры...);

Спасибо Вам огромное за

Изображение Mrgreenm

Спасибо Вам огромное за помощь! Тема исчерпана!!

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Back to top

(С) Виктор Вислобоков, 2008-2023