【问题标题】:WHERE x IN works with a single value, not with multiple on jsonWHERE x IN 适用于单个值,而不适用于 json 上的多个
【发布时间】:2023-03-17 11:20:01
【问题描述】:

在 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"}

【问题讨论】:

  • 您是否有任何示例数据可以证明该问题?
  • 任何数据都可以。假设一个表只有两列,id 和 data,其中数据是 json 类型。我在问题描述中添加了一些

标签: mysql where where-in mysql-json


【解决方案1】:

评论太长了...

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

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"}

Demo on dbfiddle

【讨论】:

  • MySQL 还提供了 ->> 运算符,它做同样的事情——取消引用由 JSON 路径提取的标量值。
  • @BillKarwin 感谢您的提醒。我已经在答案中添加了相关注释。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-28
    • 2018-12-22
    相关资源
    最近更新 更多