我在postgresql中有这个程序:
CREATE OR REPLACE FUNCTION update_meals(
integer,
integer)
RETURNS boolean AS
$BODY$
BEGIN
FOR i IN $1..$2 LOOP
UPDATE meals
SET protein = query.protein,
carbs = query.carbs,
fat = query.fat,
FROM (
SELECT meals.id as meal_id,
sum(ingredients.protein) as protein,
sum(ingredients.carbs) as carbs,
sum(ingredients.fat) as fat,
FROM meals
RIGHT OUTER JOIN mixers ON meals.id = mixers.meal_id
RIGHT OUTER JOIN ingredients ON mixers.ingredient_id = ingredients.id
RIGHT OUTER JOIN recipes ON mixers.recipe_id = recipes.id
WHERE meals.id = i
GROUP BY meals.id
) AS query
WHERE id = i;
END LOOP;
RETURN TRUE;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION update_meals(integer, integer)
OWNER TO root;
我知道如果我只能在一次更新中进行此更新,并且在时间消耗方面是否更高效。 考虑到已经减少了查询以便更好地理解,这里重要的一点是,如果我能得到当前的行'子查询上的id,表示我是否可以删除de FOR
答案 0 :(得分:0)
您可以使用单个语句将条件推送到派生表中,并在目标表上使用连接条件:
UPDATE meals
SET protein = query.protein,
carbs = query.carbs,
fat = query.fat,
FROM (
SELECT meals.id as meal_id,
sum(ingredients.protein) as protein,
sum(ingredients.carbs) as carbs,
sum(ingredients.fat) as fat,
FROM meals
RIGHT OUTER JOIN mixers ON meals.id = mixers.meal_id
RIGHT OUTER JOIN ingredients ON mixers.ingredient_id = ingredients.id
RIGHT OUTER JOIN recipes ON mixers.recipe_id = recipes.id
WHERE meals.id between $1 and $2 ---<< here
GROUP BY meals.id
) AS query
WHERE meals.id = query.meal_id --<< here;