我有一个部门表,其中有一个jsonb字段,该字段提供了工作时间,看起来像这样:

{
            "Friday": {
                "closeTime": "1970-01-01T17:00:00.000Z",
                "isOpen": true,
                "isOpen24Hours": false,
                "openTime": "1970-01-01T08:00:00.000Z"
            },
            "Monday": {
                "isOpen": false
            },
            "Saturday": {
                "isOpen": false
            },
            "Sunday": {
                "isOpen": false
            },
            "Thursday": {
                "closeTime": "1970-01-01T17:00:00.000Z",
                "isOpen": true,
                "isOpen24Hours": false,
                "openTime": "1970-01-01T08:00:00.000Z"
            },
            "Tuesday": {
                "closeTime": "1970-01-01T17:00:00.000Z",
                "isOpen": true,
                "isOpen24Hours": false,
                "openTime": "1970-01-01T08:00:00.000Z"
            },
            "Wednesday": {
                "closeTime": "1970-01-01T17:00:00.000Z",
                "isOpen": true,
                "isOpen24Hours": false,
                "openTime": "1970-01-01T08:00:00.000Z"
            }
        }

我还有另一个表,将一天的某些活动与一个部门关联起来,我想知道在活动发生的当天该部门是否开放.那么如何使用另一个表中的日期的星期几来查询这个jsonb字段呢?

我try 过这样的事情:

select a.activity_date, a.department_id, 
d.hours_of_operation->to_char(a.activity_date, 'Day')->>'isOpen' as isOpen
from activity a
join department d on a.department_id = d.id

但只有当activity_Date是星期三(这是hours_of_operation jsonb中的最后一个键)时才返回isOpen值

推荐答案

您可能忽视了Day template附带的空白填充:

DAY full upper case day name (blank-padded to 9 chars)
Day full capitalized day name (blank-padded to 9 chars)
day full lower case day name (blank-padded to 9 chars)

这意味着只有Wednesday没有任何空间,因为它已经有9个字符长了.由于额外的空白字符,其余部分最终会成为与jsonb struct 中的内容不匹配的键.在这种情况下,->返回103.Demo at db<>fiddle:

select quote_literal(to_char(a.activity_date, 'Day'))
      ,a.activity_date
      ,a.department_id
      ,(d.hours_of_operation->to_char(a.activity_date, 'Day'))->>'isOpen' as isOpen
from activity a
join department d on a.department_id = d.id
quote_literal activity_date department_id isopen
'Wednesday' 2024-04-24 1 true
'Tuesday ' 2024-04-23 1 null
'Monday ' 2024-04-22 1 null
'Sunday ' 2024-04-21 1 null
'Saturday ' 2024-04-20 1 null
'Friday ' 2024-04-19 1 null
'Thursday ' 2024-04-18 1 null
'Wednesday' 2024-04-17 1 true

trim()就好了:

select quote_literal(trim(to_char(a.activity_date, 'Day')))
      ,a.activity_date
      ,a.department_id
      ,(d.hours_of_operation->trim(to_char(a.activity_date, 'Day')))->>'isOpen' as isOpen
from activity a
join department d on a.department_id = d.id

或者在您的to_char()模板中添加fill mode FM prefix:

Modifier Description Example
FM prefix fill mode (suppress trailing zeroes and padding blanks) FM99.99
select quote_literal(to_char(a.activity_date, 'FMDay'))
      ,a.activity_date
      ,a.department_id
      ,(d.hours_of_operation->to_char(a.activity_date, 'FMDay'))->>'isOpen' as isOpen
from activity a
join department d on a.department_id = d.id
quote_literal activity_date department_id isopen
'Wednesday' 2024-04-24 1 true
'Tuesday' 2024-04-23 1 true
'Monday' 2024-04-22 1 false
'Sunday' 2024-04-21 1 false
'Saturday' 2024-04-20 1 false
'Friday' 2024-04-19 1 true
'Thursday' 2024-04-18 1 true
'Wednesday' 2024-04-17 1 true

Sql相关问答推荐

Microsoft Access UNION将长文本字段限制为255个字符

从2个表中查找每条记录的唯一最接近的日期匹配

获取每5分钟时间间隔的总和

如何更新SQLite数据库中的表?

如果元素包含通过SQL指定的字符串,则过滤掉数组元素

SQL子查询返回多个值错误

有没有办法在Postgres中存储带有时区的时间戳,而不将其转换为UTC

冲突查询的UPDATE时违反非空约束

仅当交叉应用返回单值时才更新记录

使用SQL数据库中的现有列派生或修改几个列

如何在连接中使用三个不同的列,从而在PostgreSQL中只获得两个列?

插入具有预期逻辑的查询以Forking 表

SQL中相同表内的VLOOKUP等价

按二维数组的第一个元素排序

GRAFANA 数据库查询错误:pq:列名称不存在

替换SQL Server XML中多处出现的 node 值

Oracle 21c 中的递归查询回顾过go 3 周

批量更改WooCommerce中所有产品的税收状态

如何 Select 一列具有最小值而另一列具有给定值的记录?

pyspark 将列转换为行