WHERE x IN 适用于单个值,不适用于 json 上的多个值

WHERE x IN works with a single value, not with multiple on json

在 MySQL 中的 json 字段上查询有一个难以理解的问题。 data 列的类型为 json。

下面的查询工作得很好

SELECT * FROM `someTable` WHERE data->'$.someData' in ('A')

不过下面一个returns没什么。

 SELECT * FROM `someTable` WHERE data->'$.someData' in ('A','B')

有趣的是,这也有效:

 SELECT * FROM `someTable` WHERE data->'$.someData'='A' OR data->'$.someData'='B'

我不知道为什么会这样。我最初认为 WHERE x IN 以 json 查询格式执行可能会做类似 && 但即使值是 ('A','A') 它仍然 returns 没有什么实质上表明 WHERE x IN 中的多个值不起作用。

样本数据(任何一个都可以)

id | data (json)
1  | {"someData":"A"}
2  | {"someData":"B"}

评论太长...

这似乎与 MySQL 在 IN 表达式中只有一个值时执行的优化有关(可能将其转换为 a = b 表达式)然后它忽略引号。严格来说,

SELECT * 
FROM `someTable` 
WHERE data->'$.someData' in ('A')

SELECT * 
FROM `someTable` 
WHERE data->'$.someData' = 'A'

应该return没有数据因为

SELECT data->'$.someData' 
FROM someTable;

return秒

"A"
"B"

这与 A 不同。您需要使用 JSON_UNQUOTE (or if you have MySQL 5.7.13 or later the ->> 运算符)来获取 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"}

Demo on dbfiddle

您可以尝试在子查询上使用连接而不是 IN 子句

SELECT * 
FROM `someTable` s 
INNER JOIN (
   select 'A'  col
   union 
   select 'B'
 )  t ON t.col = s.data->'$.someData