Sql在单个更新中转换更新循环

时间:2016-05-20 06:56:12

标签: sql postgresql

我在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

1 个答案:

答案 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;