我确实有一个名为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
中是否存在任何元素(不一定是全部)。
我该如何实现?
编辑
我发现了一个构建动态查询的解决方案(请参见下面的答案),这是针对PHP的问题MySQL Filter JSON_CONTAINS Any value from Array中所建议的。
答案 0 :(得分:0)
我发现自己有了一个动态查询选项的解决方案,该选项在 Edit 部分中提到过。
library(tractor.base)
condition <- function(dbcolumn,inlist){
cond <- implode(sapply(inlist, function(x) paste0("JSON_SEARCH(`",dbcolumn,"`, 'one', '", x,"') IS NOT NULL")), " OR ")
return(cond)
}
因此,如果我调用函数(问题中带有示例2):
condition("activities",inputList)
它返回:
"JSON_SEARCH(`activities`, 'one', 'hockey') IS NOT NULL OR JSON_SEARCH(`activities`, 'one', 'golf') IS NOT NULL OR JSON_SEARCH(`activities`, 'one', 'basketball') IS NOT NULL"
所以R中的MySQL查询最终看起来像这样:
query <- paste0("SELECT * FROM user_activities
WHERE ", condition("activities", inputList),";")