sql - 如何使用列表 {11:00:00,12:00:00} 选择 TO_CHAR
问题描述
我有这张桌子:
postgres::DATABASE=> SELECT * FROM db;
timeList | time
---------+------------+---------------------
{11:00:00,12:00:00} | 11:22:33
{19:00:00} | 12:12:33
我需要在timeList
几秒钟内选择值。但收到此错误:
postgres::DATABASE=> SELECT TO_CHAR(timeList, 'HH24:MI') timeList FROM db;
ERROR: syntax error at or near "timeList"
LINE 1: SELECT TO_CHAR(time, 'HH24:MI') timeList FROM db;
^
选择单个值的命令按预期工作:
postgres::DATABASE=> SELECT TO_CHAR(time, 'HH24:MI') time FROM db;
time
-------
11:22
12:12
解决方案
又快又脏
假设列"timeList"
是 type time[]
,有一种快速而肮脏的方式。强制转换为varchar(5)[]
截断时间的字符串表示,以便仅保留 HH24:MI。
test=> SELECT '{12:12, 1:1:1.123456, 23:59:59.999999}'::time[]::varchar(5)[];
varchar
---------------------
{12:12,01:01,23:59}
(1 row)
db<>在这里摆弄
它甚至可以开箱即用地表示 NULL 和空数组。“quick'n'dirty”相当干净。
当然,这取决于time
值的文本表示的实现细节。但它适用于我知道的任何可能的设置,而且我认为它不会很快改变。有关的:
缓慢而确定
要以您想要的任何方式格式化输出,Laurenz 提供的总是缓慢而可靠的方式:unnest、格式化、聚合回来。LATERAL
但是在子查询中使用 ARRAY 构造函数立即聚合回来通常更快。这也保证保持数组元素的原始顺序,而不用跟踪WITH ORDINALITY
:
SELECT *
FROM db, LATERAL (
SELECT ARRAY(SELECT to_char(unnest(db.timelist), 'HH24:MI'))
) x(times_formatted);
另外,子查询的聚合总是产生一行,所以它不会{}
在主表中默默地消除带有 NULL 或空数组 ( ) 的行(就像 Laurenz 的查询一样)。
隐式CROSS JOIN
仍然有一个副作用:它转换NULL
为一个空数组 ( {}
)。
可以通过以下方式正确避免LEFT JOIN
:
SELECT *
FROM db
LEFT JOIN LATERAL (
SELECT ARRAY(SELECT to_char(unnest(db.timelist), 'HH24:MI'))
) x(times_formatted) ON db.timelist IS NOT NULL;
考虑小提琴中的演示。
db<>在这里摆弄
有关的:
推荐阅读
- oracle - 在事务回滚的情况下处理全局临时表中的数据
- sql-server - 如何通过比较 2 个表来根据日期时间获取数据库中的最新记录
- dart - Dart2 路由器实现
- teamcity - 如何在 Teamcity 2019.1 的实验 UI 中按最新编号对构建列表进行排序
- javascript - 如何将其转换为基于类的 Javascript?
- asp.net - 哪种服务最适合在请求之间存储数据和计算某事(注入控制器)?
- regex - 带有下划线和删除额外字母的骆驼案例到蛇案例错误?
- c# - 将 Int[] 数组向下转换为 Byte[] 数组
- angular - 如何将不是使用 Angular CLI 创建的 Angular 应用程序迁移到 Angular CLI 项目?
- javascript - 确定是否安装了应用程序,如果已安装,则在应用程序中打开链接,否则导航到应用程序商店