首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PostgreSQL创建一个新列,其中的值以其他列为条件

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

Stack Overflow用户
提问于 2012-08-30 02:38:00
回答 2查看 19.2K关注 0票数 12

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

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

代码语言:javascript
复制
Survival    Survival(Days)    1-yr Survival
----------  --------------    -------------
Dead            200                NO
Alive            -                 YES
Dead            1200               YES

输入1-yr Survival条件化值的伪代码如下所示:

代码语言:javascript
复制
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语法。一些搜索结果返回“添加触发器”,但我不确定这是我需要的。我想我这里的情况要简单得多。任何帮助/建议都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-30 03:10:13

可以使用普通的UPDATE来实现一次性操作

代码语言:javascript
复制
UPDATE tbl
SET    one_year_survival = (survival OR survival_days >= 365);

我建议不要在您的名字中使用驼峰大小写、空格和括号。虽然允许在双引号之间使用,但这通常会导致复杂和混乱。考虑一下about identifiers and key words in the manual一章。

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

示例:

代码语言:javascript
复制
COPY (SELECT *, (survival OR survival_days >= 365) AS one_year_survival FROM tbl)
TO '/path/to/file.csv';

这样一开始,您就不需要冗余列了。

对评论的补充回答

要避免空更新,请执行以下操作:

代码语言:javascript
复制
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吗?

票数 10
EN

Stack Overflow用户

发布于 2012-08-30 08:49:36

老实说,我认为你最好不要将数据存储在数据库中,因为数据库可以快速、轻松地从存储的数据中计算出来。一个更好的选择是模拟一个计算字段(如下所述)。在这种情况下,您将9将空格等更改为下划线,以便于维护:

代码语言:javascript
复制
CREATE FUNCTION one_yr_survival(mytable)
RETURNS BOOL
IMMUTABLE
LANGUAGE SQL AS $$
select $1.survival OR $1.survival_days >= 365;
$$;

然后,您实际上可以:

代码语言:javascript
复制
SELECT *, m.one_year_survival from mytable m;

而且它会“正常工作”。请注意以下陷阱:

缺省列列表不会返回

  • mytable.1_year_survival,并且由于解析器会将表标识符转换为one_year_survival(m).

,因此

  • 您不能省略表标识符(上例中的m

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

实际上,您可以将此方法带到更远的地方。请参阅http://ledgersmbdev.blogspot.com/2012/08/postgresql-or-modelling-part-2-intro-to.html

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12184409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档