查询MySQL中的json字段有一个难以理解的问题。 data
列是json类型。
以下查询完全正常
SELECT * FROM `someTable` WHERE data->'$.someData' in ('A')
但是下面的一个没有返回。
SELECT * FROM `someTable` WHERE data->'$.someData' in ('A','B')
有趣的是,这也有效:
SELECT * FROM `someTable` WHERE data->'$.someData'='A' OR data->'$.someData'='B'
我对于为什么会发生这种情况一无所知。我原本以为以json查询格式执行的WHERE x IN可能会执行类似&&的操作,但即使值为('A','A'),它仍然不会返回任何基本上显示WHERE x IN中多个值的内容不会工作。
样本数据(任何人都会这样做)
id | data (json)
1 | {"someData":"A"}
2 | {"someData":"B"}
评论太长了......
当IN
表达式中只有一个值(可能将其转换为a = b
表达式)然后忽略引号时,这似乎与MySQL正在执行的优化有关。严格来说,
SELECT *
FROM `someTable`
WHERE data->'$.someData' in ('A')
要么
SELECT *
FROM `someTable`
WHERE data->'$.someData' = 'A'
应该不返回数据,因为
SELECT data->'$.someData'
FROM someTable;
回报
"A"
"B"
这与A
不一样。您需要使用JSON_UNQUOTE
(或者如果您使用MySQL 5.7.13或更高版本的->>
运算符)来获取someData
密钥的实际值:
SELECT JSON_UNQUOTE(data->'$.someData') FROm someTable;
SELECT data->>'$.someData' FROm someTable;
这使
A
B
然后使用IN
表达式正常工作:
SELECT *
FROM `someTable`
WHERE JSON_UNQUOTE(data->'$.someData') in ('A','B')
-- or use WHERE data->>'$.someData' in ('A','B')
输出:
id data
1 {"someData":"A"}
2 {"someData":"B"}
您可以尝试在子查询上使用连接而不是IN子句
SELECT *
FROM `someTable` s
INNER JOIN (
select 'A' col
union
select 'B'
) t ON t.col = s.data->'$.someData