简体   繁体   English

R 查询动态哪里有闪亮的输入

[英]R query dynamic where with shiny input

I query data from R shiny app我从 R 闪亮的应用程序查询数据

output$ceb_selector <- renderUI({
    selectInput("select_tab", label = ("ceb"),
                choices = list("xx" , "yy", "All"),
                selected = "All")

This is my old sql这是我的旧 sql

    t1 <- dbGetQuery(pool,statement = paste0("select    ",input$date," , name ,
                          sum(",input$x1,"*y) as ",input$x1," ,
                          sum(gg) as ggsum
                          from table_name 
                          where name = '",input$name,"'
                          and ",input$date," between '",input$date_range[1],"' and '",input$date_range[2],"'
                          group by ",input$date," ,name ")  )  
write.table(t1, file="emp.csv", sep = ",", row.names=FALSE)

I want to add where condition from input$ceb that have 3 choices = xx, yy, all我想添加来自 input$ceb 的 where 条件有 3 个选择 = xx, yy, all

But in database column ceb only have data xx and yy don't have all (I want use 'all' to select both xx and yy)但是在数据库列ceb只有数据xx和yy没有所有(我想使用'all'来选择xx和yy)

table桌子

inputshiny投入

What I thought is If input = xx will where ceb = xx我的想法是 If input = xx will where ceb = xx

If input = yy will where ceb = yy如果 input = yy 将 where ceb = yy

If input = All will where xx and yy如果 input = All will where xx and yy

I tried我试过

paste0("select        ",input$date," , name ,
                      sum(",input$x1,"*y) as ",input$x1," ,
                      sum(gg) as ggsum
                      from table_name 
                      where name = '",input$name,"'
                      and ",input$date," between '",input$date_range[1],"' and '",input$date_range[2],"'
                      and ceb =
                      case 
                               when  ",input$ceb," = xx then 'xx'
                               when  ",input$ceb," = yy then 'yy' 
                      end 
                      group by ",input$date," ,name ")

AND

case 
   when  ",input$ceb," = xx then and tab = 'xx'
   when  ",input$ceb," = yy then and tab = 'yy' 
end 

It's still error.还是报错。

I'm not going to be able to reproduce the full complexity of your table and shiny app, but here's a simplified local example where I think there are two methods.我将无法重现您的表和闪亮应用程序的全部复杂性,但这里有一个简化的本地示例,我认为有两种方法。

I'm using sqldf on a local frame to mimic your postgres database;我在本地框架上使用sqldf来模拟您的 postgres 数据库; I don't think the specific DBMS matters in this case.在这种情况下,我认为特定的 DBMS 并不重要。

table_name <- data.frame(
  row = 1:4,
  ceb = c('xx', 'yy', 'xx', 'yy')
)

Query formed conditionally有条件形成的查询

input_ceb <- "xx"
qry <- "select * from table_name where row > 0"
qry2 <- if (input_ceb != "All") paste("and ceb = ", sQuote(input_ceb))
sqldf::sqldf(paste(qry, qry2))
#   row ceb
# 1   1  xx
# 2   3  xx

input_ceb <- "All"
qry <- "select * from table_name where row > 0"
qry2 <- if (input_ceb != "All") paste("and ceb = ", sQuote(input_ceb))
sqldf::sqldf(paste(qry, qry2))
#   row ceb
# 1   1  xx
# 2   2  yy
# 3   3  xx
# 4   4  yy

If you look at qry2 now, it's NULL , so the query will not contain the and ceb= component.如果您现在查看qry2 ,它是NULL ,因此查询将不包含and ceb=组件。 (Note that you should make sure that the query before and after this conditionally-included portion can work equally with it present or absent.) (请注意,您应该确保在这个有条件包含的部分之前和之后的查询可以在它存在或不存在的情况下同样工作。)

Query including more conditional查询包括更多条件

(Still using input_ceb as above.) This causes the DBMS to take into consideration if ceb is "All", short-circuiting the second half. (仍然使用input_ceb如上所述。)这会导致 DBMS 考虑 ceb 是否为“全部”,从而使后半部分短路。 I don't know that this is any better, but it works the same.我不知道这是否更好,但它的工作原理是一样的。

qry <- paste(
  "select * from table_name where row > 0 and ('All' = ", sQuote(input_ceb),
  "or ceb = ", sQuote(input_ceb), ")"
)
sqldf::sqldf(qry)

Bottom line, use whichever one makes more sense to you and/or incorporates well into the rest of your query generation.最重要的是,使用对您更有意义和/或很好地融入您的查询生成的其余部分。

Notes:笔记:

  • I use sQuote here because I'm not using DBI , though like my comment on your question, you should consider being a little more defensive in your coding: use DBI::dbQuoteString in place of sQuote here.我在这里使用sQuote是因为我没有使用DBI ,尽管就像我对您的问题的评论一样,您应该考虑在编码中更具防御性:在这里使用DBI::dbQuoteString代替sQuote The DBMS may not like wrapping numbers in ticks, though, so use smartly.但是,DBMS 可能不喜欢将数字包装在刻度中,因此请明智地使用。

  • the only reason I included row > 0 was so that I had a where clause to which I could just add and ceb = '...' ;我包含row > 0的唯一原因是我有一个where子句,我可以在其中添加and ceb = '...' without row > 0 , there would be no where and therefore and would be a syntax violation.row > 0 ,就没有where ,因此and将是一个语法错误。 You won't need it, as I believe you have where clauses that are always present.您不需要它,因为我相信您有始终存在的where子句。

  • you might find sprintf or glue::glue to be slightly better for interpolating strings in there;你可能会发现sprintfglue::glue在插入字符串时稍微好一些; for instance, these are equivalent to the second example above:例如,这些相当于上面的第二个例子:

     sprintf( "select * from table_name where row > 0 and ('All' = %s or ceb = %s)", sQuote(input_ceb), sQuote(input_ceb) ) glue::glue( "select * from table_name where row > 0 and ('All' = {sQuote(input_ceb)} or ceb = {sQuote(input_ceb)})" )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM