【发布时间】:2019-09-23 19:42:39
【问题描述】:
我确实有一个名为 user_activities 的 MySQL 表,其中一列 (activities) 采用 JSON 格式:
id name activities
1 Peter ["football", "volley"]
2 Mary ["football", "hockey", "basketball"]
3 Jason ["volley", "hockey", "golf"]
我需要构建一个查询,给定一个活动列表,它将返回所有那些至少拥有此列表中的一个活动的用户。
示例 1:
给定一个列表
inputList <- list("football", "basketball")
MySQL 查询应该返回:
id name activities
1 Peter ["football", "volley"]
2 Mary ["football", "hockey", "basketball"]
示例 2:
给定一个列表
inputList <- list("hockey", "golf", "basketball")
MySQL 查询应该返回:
id name activities
2 Mary ["football", "hockey", "basketball"]
3 Jason ["volley", "hockey", "golf"]
我知道可以按活动检查每个元素是否存在,例如:
SELECT * FROM user_activities
WHERE JSON_SEARCH(`activities`, 'one', 'football') IS NOT NULL
OR JSON_SEARCH(`activities`, 'one', 'basketball') IS NOT NULL
OR JSON_SEARCH(`activities`, 'one', 'volley') IS NOT NULL
OR JSON_SEARCH(`activities`, 'one', 'hockey') IS NOT NULL
OR JSON_SEARCH(`activities`, 'one', 'golf') IS NOT NULL;
但如果一个活动不在指定列表中 (inputList),我不想在 activities 中检查它的存在。每次我运行 MySQL 查询时,这个 inputList 都会发生变化。
那么,有没有办法只检查列表中的activities 中的内容?我试过了:
SELECT * FROM user_activities
WHERE JSON_SEARCH(`activities`, 'all', (",paste(shQuote(inputList, type = "sh"), collapse = ','),")) IS NOT NULL;
但它“显然”返回错误:
`Error in .local(conn, statement, ...): could not run statement: Operand should contain 1 column(s)`
因为JSON_SEARCH 会检查 json 数组或 json 文档中是否存在单个字符串,而我没有将单个字符串放入函数中。
还有JSON_CONTAINS
SELECT * FROM user_activities
WHERE JSON_CONTAINS(`activities`->'$[*]', JSON_ARRAY(", paste(shQuote(inputList, type = "sh"), collapse = ','), "))
如果inputList 中的所有元素都存在于activities 中,则返回,并且我想要activities 中是否存在任何元素(不一定是全部)。
我怎样才能做到这一点?
编辑
我通过构建动态查询找到了一个解决方案(参见下面的答案),正如这个问题MySQL Filter JSON_CONTAINS Any value from Array for PHP 中所建议的那样。
【问题讨论】: