使用 R MySQL 上的临时 JSON 变量中的双引号
Double Quotes in temporary JSON variable on MySQL using R
我在 MYSQL 中有一个 table 包含用户与网页的交互,我需要为交互日期低于某个基准的用户提取行每个客户的日期和基准日期都不同(我从不同的数据库中提取该日期)。
我的方法是设置一个 json 变量,其中键是用户,值是基准日期,并在查询中使用它来提取预期的字段。
R 中的示例:
#MainDF contains the user and the benchmark date from a different database
json_str <- mapply(function(uid, bench_date){
paste0(
'{','"',cust,'"', ':', '"', bench_date, '"','}'
)
}, MainDF[, 'uid'],
MainDF[, 'date']
)
json_str <- paste0("'", '[', paste0(json_str , collapse = ','), ']', "'")
temp_var <- paste('set @test=', json_str)
目的是让 temp_var 成为:
set @test= '{"0001":"2010-05-05",
"0012":"2015-05-05",
"0101":"2018-07-20"}'
但实际上看起来像:
set @test= '{\"0001\":\"2010-05-05\",
\"0012\":\"2015-05-05\",
\"0101\":\"2018-07-20\"}'
然后创建主查询:
main_Q <- "select user_id, date
from interaction
where 1=1
and json_contains(json_keys(@test), concat('\"',user_id,'\"')) = 1
and date <= json_unquote(json_extract(@test,
concat('$.','\"',user_id, '\"')
)
)
"
对于执行,首先设置时间变量,然后执行主查询
dbSendQuery(connection, temp_var)
resp <- dbSendQuery(connection, main_Q )
target_df <- fetch(resp, n=-1)
dbClearResult(resp )
当我在 SQL IDE 中测试它的一小部分时,它确实有效。但是,在 R 中它没有 return 任何东西。
我认为问题是 R 转义 temp_var 和 SQL 中的双引号最终读取
set @test= '{\"0001\":\"2010-05-05\",
\"0012\":\"2015-05-05\",
\"0101\":\"2018-07-20\"}'
这不是行不通的。
例如,如果我执行:
set @test= '{"0001":"2010-05-05",
"0012":"2015-05-05",
"0101":"2018-07-20"}'
select json_keys(@test)
它将return一个带有键的数组,但
不是这样
set @test= '{\"0001\":\"2010-05-05\",
\"0012\":\"2015-05-05\",
\"0101\":\"2018-07-20\"}'
select json_keys(@test)
我不确定如何解决这个问题,但我需要双引号来指定 JSON。有没有我应该尝试的任何其他方法或使这项工作有效的方法?
首先,出于几个原因,我认为通常使用众所周知的 library/package 来转换 to/from JSON 更好。
这为您提供了一个字符串,您应该可以将其放置在几乎任何地方。
json_str <- jsonlite::toJSON(setNames(as.list(MainDF$date), MainDF$uid), auto_unbox=TRUE)
json_str
# {"0001":"2010-05-05","0012":"2015-05-05","0101":"2018-07-20"}
虽然 在 R 控制台上查看 对象将给出转义双引号,
as.character(json_str)
# [1] "{\"0001\":\"2010-05-05\",\"0012\":\"2015-05-05\",\"0101\":\"2018-07-20\"}"
这仅仅是 R 的表示(显示双引号内的所有字符串,因此需要转义字符串内的任何双引号)。
将它添加到一些脚本中应该是直截了当的:
cat(paste('set @test=', sQuote(json_str)), '\n')
# set @test= '{"0001":"2010-05-05","0012":"2015-05-05","0101":"2018-07-20"}'
我假设每个都在自己的行中并不重要。如果是,并且缩进很重要,也许这更符合您的风格:
spaces <- strrep(' ', 2+nchar('set @test = '))
cat(paste0('set @test = ', sQuote(gsub(",", paste0(",\n", spaces), json_str))), '\n')
# set @test = '{"0001":"2010-05-05",
# "0012":"2015-05-05",
# "0101":"2018-07-20"}'
数据:
MainDF <- read.csv(stringsAsFactors=FALSE, colClasses='character', text='
uid,date
0001,2010-05-05
0012,2015-05-05
0101,2018-07-20')
我在 MYSQL 中有一个 table 包含用户与网页的交互,我需要为交互日期低于某个基准的用户提取行每个客户的日期和基准日期都不同(我从不同的数据库中提取该日期)。
我的方法是设置一个 json 变量,其中键是用户,值是基准日期,并在查询中使用它来提取预期的字段。
R 中的示例:
#MainDF contains the user and the benchmark date from a different database
json_str <- mapply(function(uid, bench_date){
paste0(
'{','"',cust,'"', ':', '"', bench_date, '"','}'
)
}, MainDF[, 'uid'],
MainDF[, 'date']
)
json_str <- paste0("'", '[', paste0(json_str , collapse = ','), ']', "'")
temp_var <- paste('set @test=', json_str)
目的是让 temp_var 成为:
set @test= '{"0001":"2010-05-05",
"0012":"2015-05-05",
"0101":"2018-07-20"}'
但实际上看起来像:
set @test= '{\"0001\":\"2010-05-05\",
\"0012\":\"2015-05-05\",
\"0101\":\"2018-07-20\"}'
然后创建主查询:
main_Q <- "select user_id, date
from interaction
where 1=1
and json_contains(json_keys(@test), concat('\"',user_id,'\"')) = 1
and date <= json_unquote(json_extract(@test,
concat('$.','\"',user_id, '\"')
)
)
"
对于执行,首先设置时间变量,然后执行主查询
dbSendQuery(connection, temp_var)
resp <- dbSendQuery(connection, main_Q )
target_df <- fetch(resp, n=-1)
dbClearResult(resp )
当我在 SQL IDE 中测试它的一小部分时,它确实有效。但是,在 R 中它没有 return 任何东西。 我认为问题是 R 转义 temp_var 和 SQL 中的双引号最终读取
set @test= '{\"0001\":\"2010-05-05\",
\"0012\":\"2015-05-05\",
\"0101\":\"2018-07-20\"}'
这不是行不通的。 例如,如果我执行:
set @test= '{"0001":"2010-05-05",
"0012":"2015-05-05",
"0101":"2018-07-20"}'
select json_keys(@test)
它将return一个带有键的数组,但
不是这样set @test= '{\"0001\":\"2010-05-05\",
\"0012\":\"2015-05-05\",
\"0101\":\"2018-07-20\"}'
select json_keys(@test)
我不确定如何解决这个问题,但我需要双引号来指定 JSON。有没有我应该尝试的任何其他方法或使这项工作有效的方法?
首先,出于几个原因,我认为通常使用众所周知的 library/package 来转换 to/from JSON 更好。
这为您提供了一个字符串,您应该可以将其放置在几乎任何地方。
json_str <- jsonlite::toJSON(setNames(as.list(MainDF$date), MainDF$uid), auto_unbox=TRUE)
json_str
# {"0001":"2010-05-05","0012":"2015-05-05","0101":"2018-07-20"}
虽然 在 R 控制台上查看 对象将给出转义双引号,
as.character(json_str)
# [1] "{\"0001\":\"2010-05-05\",\"0012\":\"2015-05-05\",\"0101\":\"2018-07-20\"}"
这仅仅是 R 的表示(显示双引号内的所有字符串,因此需要转义字符串内的任何双引号)。
将它添加到一些脚本中应该是直截了当的:
cat(paste('set @test=', sQuote(json_str)), '\n')
# set @test= '{"0001":"2010-05-05","0012":"2015-05-05","0101":"2018-07-20"}'
我假设每个都在自己的行中并不重要。如果是,并且缩进很重要,也许这更符合您的风格:
spaces <- strrep(' ', 2+nchar('set @test = '))
cat(paste0('set @test = ', sQuote(gsub(",", paste0(",\n", spaces), json_str))), '\n')
# set @test = '{"0001":"2010-05-05",
# "0012":"2015-05-05",
# "0101":"2018-07-20"}'
数据:
MainDF <- read.csv(stringsAsFactors=FALSE, colClasses='character', text='
uid,date
0001,2010-05-05
0012,2015-05-05
0101,2018-07-20')