根据其他列 PSQL 的值在 SELECT 语句中添加附加列

Posted

技术标签:

【中文标题】根据其他列 PSQL 的值在 SELECT 语句中添加附加列【英文标题】:Add additional column in a SELECT statement based on values of other columns PSQL 【发布时间】:2016-06-08 08:16:52 【问题描述】:

我有一张每人驾驶执照的表格,并且知道某人何时获得驾驶执照。驾照的有效期可以是您获得驾照之日起 X 天,也可以是特定日期。

 acquired        relative      specific_date      valid_type     expiration_date
----------------------------------------------------------------------------------
2015-02-05         500             null              days
2015-02-05         null         2016-03-05           date
2015-02-05         200             null              days
2015-02-05         null         2016-02-22           date

我现在的查询是:

SELECT acquired,
       relative_date,
       specific_date,
       valid_type
FROM person_drivers_license
WHERE (valid_type = 'days'
       AND (EXTRACT(epoch
                    FROM acquired) - EXTRACT(epoch
                                             FROM now()))/86400 + relative_date > 0)
  OR (valid_type = 'DATE'
      AND specific_date >= now()));

我正在尝试使用上面的 select 语句添加 expire_date 列。如果是特定日期,只需将日期放入 expire_date 中,如果是相对日期,则在获取日期的帮助下计算到期日期。这在 PSQL 中可行吗?

【问题讨论】:

检查COALESCE()函数。或者更复杂的CASE WHEN ... THEN ... ELSE END 输出应该是什么? 这应该是我写的那张表,其中的 expire_date 列填充了许可到期的日期。 【参考方案1】:

你不需要pl/sql

SELECT acquired,
       relative_date,
       specific_date,
       valid_type,
       CASE WHEN specific date = "date" -- starts here
       THEN specific date 
       ELSE acquired + cast('1 months' as interval)END 
       AS expiration_date -- end here
FROM person_drivers_license
WHERE (valid_type = 'days'
       AND (EXTRACT(epoch
                    FROM acquired) - EXTRACT(epoch
                                             FROM now()))/86400 + relative_date > 0)
  OR (valid_type = 'DATE'
      AND specific_date >= now()));

【讨论】:

Postgres 没有DateAdd() 功能。请阅读 postgres 手册以获取日期数学示例:postgresql.org/docs/current/static/functions-datetime.html 确实是@IgorRomanchenko。答案已修改。感谢您让我注意到它。【参考方案2】:

首先 - 在 postgres 中有一种更简单的日期数学运算方法。你可以使用类似的东西:

acquired + relative_date * interval '1 day' >= current_date

acquired + relative_date >= current_date 
-- any integer can be treated as interval in days for date mathematics is SQL

对于这个问题 - 试试这个:

CASE WHEN valid_type = 'days' 
     THEN acquired + relative_date * interval '1 day'
     WHEN valid_type = 'date'
     THEN specific_date
     --ELSE ??? you may specify something here
END

COALESCE(specific_date, acquired + relative_date * interval '1 day')

查询可能如下所示:

SELECT acquired,
       relative_date,
       specific_date,
       valid_type,
       COALESCE(specific_date, acquired + relative_date * interval '1 day') as valid_date
FROM person_drivers_license
WHERE COALESCE(specific_date, acquired + relative_date * interval '1 day') >= current_date

【讨论】:

谢谢!这工作除了一件小事。我也得到了时间,而不仅仅是我的新专栏中的日期。可能是因为我获取的列有时间戳 @uraza 这意味着输入之一是timestamp,而不是实际日期。您可以cast(... as date)timestamp 截断为date。顺便说一句,now() 返回timestampcurrent_date 返回date【参考方案3】:

试试这个:

SELECT acquired,
       relative_date,
       specific_date,
       valid_type
       CASE valid_type
         WHEN 'days' THEN acquired + relative_date
         WHEN 'date' THEN specific_date
         ELSE NULL
       END AS expiration_date
FROM   person_drivers_license;

【讨论】:

以上是关于根据其他列 PSQL 的值在 SELECT 语句中添加附加列的主要内容,如果未能解决你的问题,请参考以下文章

根据其他列的值在多索引数据框中创建新列的简单方法

如何根据列渲染器中的值在网格列中显示图像?

根据上一列中的值在 Python Dataframe 中构建行

PSQL - 查找所有值并根据另一列中的非唯一值使其唯一

使用正则表达式根据列的值在数据集中创建新列

根据其他两列的值在 Pandas 中创建一个新列[重复]