Passing a SQL input date range into a query in SHINY

♀尐吖头ヾ 提交于 2019-12-11 07:28:52

问题


I'm learning to use Shiny and shiny dashboard and working with a sql database SQL-SERVER where I'd like to pull the data straight from the database. Essentially the idea is to merge to columns in a table that have a start spot and a stop spot for a date range, tabulate them and then diagram them.

I found the following posting on how to pass sql input statements into shiny: How to pass input variable to SQL statement in R shiny?

Unfortunately when I try and apply this I get an error 'subscript is out of bounds; it looks like the query isn't being pulled in. I've tested it separately and was able to pull the data and run through each step without issue. I am using the RODBC package which I wonder if this is the issue. Below is my code:

         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)

I'm sure this is some silly mistake, a missing quotation mark or a misunderstanding on my part of how to apply these techniques. Appreciate the help!!

                ##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() 

}
    })

   }

Putting up edits to the server following suggestions by NJburgo ##################################NJburgo suggestion################ #I get the error: Do not know how to convert input$dates to class date

                       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() 

               })

             }

回答1:


##########################figured out answer. It required a combination of both suggestions from all of you making sure date printed and was converted as well. Thank you all!Below is working code
                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)



回答2:


I don't think this as R thing, more likely SQL, especially if your query works with ordinary dates outside of Shiny (hint: test this, report back!).

For date comparison in SQL have always had to convert the date as so:

...WHERE col_name >= {d '2016-08-04'}...

So you have to format the date in R. The simplest way to do this is with format:

format(Sys.Date(), "{d '%Y-%m-%d'}")


来源:https://stackoverflow.com/questions/38770684/passing-a-sql-input-date-range-into-a-query-in-shiny

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!