Postgresql:从select更新列并在返回多行时添加条件。

3

我需要使用SELECT更新一列,SELECT语句可能返回多个值。如果发生这种情况,我想应用第二个条件来确定哪个值被选择:

UPDATE train
SET var1 = (
    CASE
        WHEN (SELECT COUNT(*)
              FROM cars
              WHERE (train.var2 LIKE cars.var2))
             > 1)
        THEN (
            SELECT var1
            FROM cars
            WHERE (train.var2 LIKE cars.var2)
              AND cars.var2 in (
                SELECT var2
                FROM cars
                WHERE train.user_id = cars.user_id)
        )
        ELSE (
            SELECT var1
            FROM cars
        WHERE (train.var2 LIKE cars.var2))
        )
    END
);

我认为上述方法可行,但我执行了3次相同的SELECT语句。您是否有更好的方法来避免这种情况?也许有一种简单的方法可以捕获SELECT返回多个值时立即执行相关操作?
谢谢。
2个回答

2
update train set
  var1 = (
    select cars.var1
    from cars
    where train.var2 like cars.var2
    order by train.user_id = cars.user_id desc
    limit 1);

@Alexandre 刚刚意识到了这一点。你的解决方案和我的解决方案之间存在逻辑上的差异。如果有几行数据,其中 train.var2 类似于 cars.var2,但没有任何一行数据 train.user_id = cars.user_id,则你的解决方案返回 NULL,而我的解决方案返回第一行随机数据。所以要小心。祝好运 ) - Abelisto
谢谢,我在我的项目中成功地避开了这个差异 :) - Alexandre

1
上面的答案很好,并且可以直接使用。如果你需要做很多这样的操作,请看一下:https://wiki.postgresql.org/wiki/First/last_(aggregate) 然后你可以这样做:
update train set
  var1 = (
    select first(cars.var1 order by train.user_id = cars.user_id desc)
    from cars
    where train.var2 like cars.var2
  );

根据您的具体使用情况,这可能更整洁、更易读、更易于理解(在子查询中使用order by充满了讨厌的边缘情况),或者只是不值得麻烦。


最终我选择了@Abelisto的选项,因为IntelliJ无法识别Postgres中的“first”,而我又不想深入研究它:) 无论如何,还是谢谢你。 - Alexandre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接