我使用PostgreSQL 9.1.2并且我有一个基本表,如下所示,我将条目的生存状态作为布尔值(Survival)
以及天数(Survival(Days))
。
我手动添加了一个名为1-yr Survival
的新列,现在我想为表中的每个条目填写此列的值,条件是该条目的Survival
和Survival (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语法。一些搜索结果返回“添加触发器”,但我不确定这是我所需要的。我认为我的情况要简单得多。任何帮助/建议将不胜感激。
答案 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;
它将“正常工作”。请注意以下问题:
然而,好处是可以证明该值永远不会与其他值不同步。否则你最终会得到一个检查约束的老鼠窝。
你实际上可以采用这种方法。见http://ledgersmbdev.blogspot.com/2012/08/postgresql-or-modelling-part-2-intro-to.html