我试图对我的postgres数据库运行以下查询:
select distinct offer_id from offers
where listing_id = 2299392
group by offer_id
having not bool_or(status in ('Rejected', 'Draft') or (status = 'Pending' and expiry_date < now())
or (seller_t_and_c_accepted = true and buyer_t_and_c_accepted = true and
( (seller_conditions = null and buyer_conditions = null) -- neither buyer nor seller have any conditions
-- seller has conditions and they are all done
or (buyer_conditions = null and not exists (select * from json_each(offers.seller_conditions::json) as sc(key,val) where (sc.val -> 'done')::text = 'false' or sc.val ? 'done'))
-- buyer has conditions and they are all done
or (seller_conditions = null and not exists (select * from json_each(offers.buyer_conditions::json) as bc(key,val) where (bc.val -> 'done')::text = 'false' or bc.val ? 'done'))
-- both buyer and seller have conditions and they are all done
or (not exists (select * from json_each(offers.buyer_conditions::json) as bc(key,val) where (bc.val -> 'done')::text = 'false' or sc.val ? 'done') and not exists (select * from json_each(offers.seller_conditions::json) as sc(key,val) where (sc.val -> 'done')::text = 'false' or sc.val ? 'done'))
)
)
)
我得到一个错误:
operator does not exist: json ? unknown
当我向上述查询中添加以下内容时,就会发生这种情况:
sc.val ? 'done'
...
bc.val ? 'done'
我不是sql或postgresMaven,但我认为json是一个对象如果“field”是存在于json对象中的字段的名称,则“field”应返回true,否则返回false(即,如果它不存在于json对象中)。
我不认为您需要知道我在上面的查询中试图完成什么,但是它可能会有所帮助,所以我将为您详细介绍。
我正在尝试获取给定房地产清单的所有有效报价(在本例中,是id为2299392的清单)。挂牌交易中的主动要约是指未被拒绝、未起草、未过期和未完成的要约。“完整”报价是指买方和卖方均已接受条款和条件,且满足所有买方条件(如有)和所有卖方条件(如有)的报价。
在上面的查询中,“完整”报价的条件是最复杂的,所以我将进一步细分。首先是这样的:
...or (seller_t_and_c_accepted = true and buyer_t_and_c_accepted = true and
买方和卖方都接受了条款和条件。。。
( (seller_conditions = null and buyer_conditions = null) or ...
包括买方和卖方都没有任何条件的情况。
(buyer_conditions = null and not exists (select * from json_each(offers.seller_conditions::json) as sc(key,val) where (sc.val -> 'done')::text = 'false' or sc.val ? 'done')) or...
包括买方没有条件但卖方有条件的情况。条件存储为json对象:
{
"Subject to financing": {"date": "2020-03-19", "time": "2100", "done": false},
"Subject to inspection": {"date": "2020-03-19", "time": "2100", "done": true}
}
它本质上是一系列的条件,每一个条件本身就是一个json对象,包含一个截止日期(日期和时间)以及是否满足(完成)。
为了通过解析来查看是否满足所有条件,我有一个嵌套的select:
select * from json_each(offers.seller_conditions::json) as sc(key,val) where (sc.val -> 'done')::text = 'false' or sc.val ? 'done'
我使用json_遍历所有条件,并获得键/值对(因此键可能是“subject to financing”,值是{“date”:“2020-03-19”,“time”:“2100”,“done”:false})。然后我检查这个值,看“done”字段是否为false(意味着这个条件不满足,因此属于我的结果)。我还检查该值是否有一个名为“done”的字段(因为有时不会,如:{“date”:“2020-03-19”,“time”:“2100”})这部分抛出了一个错误:operator不存在:json?未知。
不管怎样,其余的都差不多:
(seller_conditions = null and not exists (select * from json_each(offers.buyer_conditions::json) as bc(key,val) where (bc.val -> 'done')::text = 'false' or bc.val ? 'done')) or ...
包括卖方没有条件但买方有条件的情况,以及:
(not exists (select * from json_each(offers.buyer_conditions::json) as bc(key,val) where (bc.val -> 'done')::text = 'false' or sc.val ? 'done') and not exists (select * from json_each(offers.seller_conditions::json) as sc(key,val) where (sc.val -> 'done')::text = 'false' or sc.val ? 'done'))
包括买卖双方都有条件的情况。
不管怎样,有人知道为什么它会告诉我?操作员不存在?我写错了吗?有没有别的方法来实现我的愿望?谢谢。
1条答案
按热度按时间jjhzyzn01#
这个?运算符只为jsonb定义,不为json定义。注意,docs有两个表,一个用于双类型运算符,另一个仅用于jsonb。
您需要将值转换为jsonb。理想情况下,您可以将列类型更改为jsonb,然后一直使用jsonb操作符/函数。