PostgreSQL中JSON列转UUID实现IN查询及问答统计
问题背景
你需要统计问答消息的对应关系:
- 问题消息:
node或options列非空的记录 - 回答消息:
previous列非空的记录
最终要输出类似这样的统计结果:
| message | answer | count |
|---|---|---|
| Stuffed crust? | Crunchy crust | 2 |
| Stuffed crust? | More cheese! | 1 |
| Pineapple on pizza? | No | 3 |
| Pineapple on pizza? | Yes | 2 |
一开始的查询遇到了类型转换错误,报错信息:
ERROR: ERROR: operator does not exist: json = uuid
LINE 24: where previous->'id'::text in (
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
错误原因
这个错误出在类型匹配上:你尝试把JSON类型的previous->'id'(即使转成text)和UUID类型的id直接比较,但两者类型不兼容。previous->'id'返回的是带引号的JSON字符串值,而id是原生UUID类型,直接对比就会触发类型不匹配报错。
解决方案
核心是正确提取JSON中的字符串值并转换为UUID类型,再和问题消息的id关联。以下是修正后的查询语句,完全满足你的统计需求:
```费 Normally` Bar拆分: Ref雅亚太MOracle戴需要 combine不移第一次佐贺错误,直接上正确的:
select
d2.message as question,
data.message as answer,
count(data.message) as count
from data
join data as d2 on (data.previous->>'id')::uuid = d2.id
where (data.previous->>'id')::uuid in (
SELECT id FROM data WHERE options is not null
)
group by question, data.message;
### 关键修正点: - 用`previous->>'id'`替代`previous->'id'`:`->>`会直接提取JSON字段的纯字符串值(去掉引号),而`->`返回的是JSON类型对象 - 通过`::uuid`显式将提取的字符串转换为UUID类型,和`d2.id`的UUID类型完美匹配 执行这个查询后,就能得到你需要的问答统计结果了。 内容的提问来源于stack exchange,提问作者Ben Swinburne

