Sql server 将SQL输入日期范围传递到数据库中的查询
我正在学习使用闪亮的仪表板,并使用sql数据库sql-SERVER,在这里我想直接从数据库中提取数据。基本上,这个想法是合并到一个表中有一个日期范围的开始点和结束点的列,将它们制成表格,然后绘制它们的图表 我发现了以下关于如何将sql输入语句传递到系统的帖子: 不幸的是,当我尝试应用它时,我得到了一个错误“下标超出范围”;看起来查询没有被拉入。我已经分别测试了它,并且能够提取数据并顺利完成每个步骤。我正在使用RODBC包,我想知道这是否是问题所在。下面是我的代码:Sql server 将SQL输入日期范围传递到数据库中的查询,sql-server,r,shiny,rodbc,shinydashboard,Sql Server,R,Shiny,Rodbc,Shinydashboard,我正在学习使用闪亮的仪表板,并使用sql数据库sql-SERVER,在这里我想直接从数据库中提取数据。基本上,这个想法是合并到一个表中有一个日期范围的开始点和结束点的列,将它们制成表格,然后绘制它们的图表 我发现了以下关于如何将sql输入语句传递到系统的帖子: 不幸的是,当我尝试应用它时,我得到了一个错误“下标超出范围”;看起来查询没有被拉入。我已经分别测试了它,并且能够提取数据并顺利完成每个步骤。我正在使用RODBC包,我想知道这是否是问题所在。下面是我的代码: libra
library(stringr)
library(RODBC)
library(circlize)
library(shinydashboard)
library(shiny)
ui <- dashboardPage(skin = "blue",
dashboardHeader(title = "sample"),
dashboardSidebar(disable = TRUE),
dashboardBody(
# Boxes need to be put in a row (or column)
fluidRow(
box(title = "Route Volume", background = "green", solidHeader = TRUE,
plotOutput(outputId= 'plot2'))),
fluidRow(
box(background= "green", dateRangeInput("dates", label = h3("Date Range"),start = '2016-06-01',
end = '2016-06-05')), width = 4
))))
server <- function(input, output) {
database = odbcConnect("datatbase")
output$plot2 = renderPlot({
d = paste0("SELECT
top 30
convert(char(10),datetime,121) as date,
cast(start_destination as varchar(3))
+ (',') + cast(final_destination as varchar(3)) as combo,
count(cast(start_destination as varchar(3))
+ (',') + cast(final_destination as varchar(3))) as volume
FROM
trips
WHERE datetime >= ",input$dates[1]," AND
datetime < ",input$dates[2],"
GROUP BY
cast(start_destination as varchar(3))
+ (',') + cast(final_destination as varchar(3)),
convert(char(10),datetime,121);")
sql = sqlQuery(database, d)
sql = data.frame(sql, do.call(rbind, str_split(sql$combo, ',')))
colnames(sql)[colnames(sql)=="X1"] <- "From"
colnames(sql)[colnames(sql)=="X2"] <- "To"
sql = sql[,c(4,5,3)]
sql = sql[order(sql$volume, decreasing = T),]
chordDiagram(sql)
circos.clear()
})
}
shinyApp(ui, server)
我确信这是一个愚蠢的错误,缺少引号,或者是我对如何应用这些技术的误解。谢谢你的帮助
##adding edits by Dean to test
database = odbcConnect("database")
output$plot2 = renderPlot({
if(input$dates[1]!= "") {
d = paste0("SELECT
top 30
convert(char(10),datetime,121) as date,
cast(start_destination as varchar(3))
+ (',') + cast(final_destination as varchar(3)) as combo,
count(cast(start_destination as varchar(3))
+ (',') + cast(final_destination as varchar(3))) as volume
FROM
trips
WHERE
datetime >= ",input$dates[1]," AND
datetime < ",input$dates[2],"
GROUP BY
cast(start_destination as varchar(3))
+ (',') + cast(final_destination as varchar(3)),
convert(char(10),datetime,121);")
sql = sqlQuery(database, d)
#i assumed the if statement ended here so I put the
#bracket below
sql = data.frame(sql, do.call(rbind, str_split(sql$combo, ',')))
colnames(sql)[colnames(sql)=="X1"] <- "From"
colnames(sql)[colnames(sql)=="X2"] <- "To"
sql = sql[,c(4,5,3)]
sql = sql[order(sql$volume, decreasing = T),]
chordDiagram(sql)
circos.clear()
}
})
}
按照Njpurgo的建议对服务器进行编辑
Njpurgo建议
我得到的错误是:不知道如何将输入的$dates转换为类日期
database = odbcConnect("database")
output$plot2 = renderPlot({
dates = as.Date(input$dates)
d = paste0("SELECT
top 30
convert(char(10),datetime,121) as date,
cast(start_destination as varchar(3))
+ (',') + cast(final_destination as varchar(3)) as combo,
count(cast(start_destination as varchar(3))
+ (',') + cast(final_destination as varchar(3))) as volume
FROM
trips
WHERE
datetime >= {d '",input$dates[1],"'} AND
datetime < {d '",input$dates[2],"'}
GROUP BY
cast(start_destination as varchar(3))
+ (',') + cast(final_destination as varchar(3)),
convert(char(10),datetime,121);")
sql = sqlQuery(database, d)
sql = data.frame(sql, do.call(rbind, str_split(sql$combo, ',')))
colnames(sql)[colnames(sql)=="X1"] <- "From"
colnames(sql)[colnames(sql)=="X2"] <- "To"
sql = sql[,c(4,5,3)]
sql = sql[order(sql$volume, decreasing = T),]
chordDiagram(sql)
circos.clear()
})
}
我不认为这是R的东西,更可能是SQL,特别是如果您的查询使用的是普通日期,而不是闪亮的提示:测试这个,报告回来 对于SQL中的日期比较,始终必须将日期转换为:
...WHERE col_name >= {d '2016-08-04'}...
因此,您必须以R格式设置日期。最简单的方法是使用格式:
format(Sys.Date(), "{d '%Y-%m-%d'}")
找到了答案。它需要你们所有人的两个建议的组合,确保打印日期和转换日期。谢谢大家!!下面是工作代码
server <- function(input, output) {
output$plot2 = renderPlot({
database = odbcConnect("database")
start_date = print(input$dates[1])
end_date = print(input$dates[2])
my_query="SELECT
top 30
convert(char(10),datetime,121) as date,
cast(start_destination as varchar(3))
+ (',') + cast(final_destination as varchar(3)) as combo,
count(cast(start_destination as varchar(3))
+ (',') + cast(final_destination as varchar(3))) as volume
FROM
trips
WHERE
datetime >= DATE1 AND
datetime < DATE2
GROUP BY
cast(start_destination as varchar(3))
+ (',') + cast(final_destination as varchar(3)),
convert(char(10),datetime,121);"
my_query <- sub("DATE1",as.Date(start_date),my_query);
my_query <- sub("DATE2",as.Date(end_date),my_query)
sql = sqlQuery(database, paste(my_query))
sql = data.frame(sql, do.call(rbind, str_split(sql$combo, ',')))
colnames(sql)[colnames(sql)=="X1"] <- "From"
colnames(sql)[colnames(sql)=="X2"] <- "To"
sql = sql[,c(4,5,3)]
sql = sql[order(sql$volume, decreasing = T),]
chordDiagram(sql)
circos.clear()
})
}
shinyApp(ui, server)
如果避免字符串连接并使用参数化查询,则不必转换日期。如果必须使用它们,则明确的日期格式是未分离的格式,即20160804。在任何情况下,使用RodbText都更容易、更安全,它支持感谢提示。Panagiotos,我认为参数化查询肯定是在这之后我需要移动的地方,但我不确定这是问题所在。查询在shiny外部运行良好,在shiny内部停止。我继续尝试了Njpurgo的解决方案:其中col_name>={d',输入$dates[1],},这样数据就转换成了日期格式,但仍然没有成功,这在shiny之外确实有效。我确实注意到,当我将日期硬编码到查询中时,效果很好。因此,我认为问题在于输入$日期。不知道在哪里。有什么想法吗?@LoF10,在这里,selectDate的输入是一个字符串,需要转换。使用date Hey Njpurgo,谢谢更新,所以我继续尝试。不起作用,但可能是我设置的方式。如果你能快速看一下,我在上面的帖子中添加了编辑。我不确定我是应该同时转换日期[1]和日期[2],还是只转换“日期”。无论哪种方式,我都遇到了错误。我不知道如何将输入$dates转换为类Date。我还尝试了dates=formatinput$dates,“%Y%m%d”,这导致了错误:$:$运算符中的错误对于原子向量无效使用字符串连接来构造SQL查询本身就是一个错误。日期和数字参数的意外转换只是它可能导致的问题之一。使用适当的方法避免所有引用、格式和安全问题一个猜测是shiny在输入$dates值之前运行sql。我会在sql查询发生之前放置printinput$dates[1]和printinput$dates[2],然后运行应用程序。这假设您是从Rstudio运行的,这样您就可以在Rstudio窗口中看到它打印的内容。我试着打印输入的$日期,但没有任何区别。我确信问题就在这里,因为当日期被硬编码时,数据就不会有问题了。我没想到打印会有什么不同。这只是一个调试步骤。它是打印日期还是空白?明白了。它没有打印任何东西。只是空白,就好像shiny没有解释要放入SQL查询的输入$dates,这就是为什么查询也是空白的