PostgreSQL创建一个新列,其值以其他列为条件

时间:2012-08-29 18:38:00

标签: postgresql insert-update conditional-statements

我使用PostgreSQL 9.1.2并且我有一个基本表,如下所示,我将条目的生存状态作为布尔值(Survival)以及天数(Survival(Days))

我手动添加了一个名为1-yr Survival的新列,现在我想为表中的每个条目填写此列的值,条件是该条目的SurvivalSurvival (Days)列值。一旦完成,数据库表将如下所示:

Survival    Survival(Days)    1-yr Survival
----------  --------------    -------------
Dead            200                NO
Alive            -                 YES
Dead            1200               YES

输入1-yr Survival的条件值的伪代码类似于:

ALTER TABLE mytable ADD COLUMN "1-yr Survival" text
for each row
if ("Survival" = Dead & "Survival(Days)" < 365) then Update "1-yr Survival" = NO
else Update "1-yr Survival" = YES
end 

我相信这是一个基本的操作,但是我没有找到执行它的postgresql语法。一些搜索结果返回“添加触发器”,但我不确定这是我所需要的。我认为我的情况要简单得多。任何帮助/建议将不胜感激。

2 个答案:

答案 0 :(得分:8)

使用普通UPDATE

可以实现一次性操作
UPDATE tbl
SET    one_year_survival = (survival OR survival_days >= 365);

我建议不要在你的名字中使用驼峰,空格和括号。虽然在双引号之间允许,但它常常导致并发症和混乱。考虑章节about identifiers and key words in the manual

您是否知道可以使用COPY 将查询结果导出为CSV? 例如:

COPY (SELECT *, (survival OR survival_days >= 365) AS one_year_survival FROM tbl)
TO '/path/to/file.csv';

您不需要以这种方式开始使用冗余列。


评论的补充答案

避免空更新:

UPDATE tbl
SET    "Dead after 1-yr" = (dead AND my_survival_col < 365)
      ,"Dead after 2-yrs" = (dead AND my_survival_col < 730)
....
WHERE  "Dead after 1-yr" IS DISTINCT FROM (dead AND my_survival_col < 365)
   OR  "Dead after 2-yrs" IS DISTINCT FROM (dead AND my_survival_col < 730)
...

就个人而言,如果我有令人信服的理由,我只会添加这些冗余列。通常我不会。如果是关于绩效:你知道indexes on expressions and partial indexes吗?

答案 1 :(得分:5)

老实说,我认为最好不要在数据库中存储数据,这可以通过存储数据快速轻松地计算出来。一个更好的选择是模拟一个计算字段(然而,下面提到的问题)。在这种情况下,您可以将空格等更改为下划线以便于维护:

CREATE FUNCTION one_yr_survival(mytable)
RETURNS BOOL
IMMUTABLE
LANGUAGE SQL AS $$
select $1.survival OR $1.survival_days >= 365;
$$;

那么你实际上可以:

SELECT *, m.one_year_survival from mytable m;

它将“正常工作”。请注意以下问题:

  • mytable.1_year_survival将不会被默认列列表和
  • 返回
  • 您不能省略表标识符(上例中的m),因为解析器将其转换为one_year_survival(m)。

然而,好处是可以证明该值永远不会与其他值不同步。否则你最终会得到一个检查约束的老鼠窝。

你实际上可以采用这种方法。见http://ledgersmbdev.blogspot.com/2012/08/postgresql-or-modelling-part-2-intro-to.html

相关问题