Существует ли dplyr-способ написания сводных SQL-запросов с условиями?

#sql #r #database #postgresql #dplyr

#sql #r #База данных #postgresql #dplyr

Вопрос:

У меня есть некоторые данные в базе данных SQL, и я установил соединение через RStudio. Поэтому я ссылаюсь на свои данные с помощью tbl ():

 data = tibble(id = c(65000, 65000, 65000, 65005, 65005, 65005, 65010, 65010, 65010), stock = c(12, 7, -4, 54, 51, 46, 183, 89, -1), week = c(43,44,45,43,44,45,43,44,45))

> tbl(connection, "data")
# Source:   table<data> [?? x 3]
# Database: postgres 13.0.0 [postgres@localhost:5432/postgres]
     id stock  week
  <dbl> <dbl> <dbl>
1 65000    12    43
2 65000     7    44
3 65000    -4    45
4 65005    54    43
5 65005    51    44
6 65005    46    45
7 65010   183    43
8 65010    89    44
9 65010    -1    45
  

Поскольку я не очень хорошо знаком с SQL, я придерживаюсь запросов dyplr. Я хотел бы рассчитать соотношение элементов (id), доступных за данную неделю, и попробовать следующее:

 tbl(connection, "data")%>%summarise(r=mean(stock>0))
  

Однако я получаю сообщение INT: No function matches the given name and argument types. You might need to add explicit type casts. , и кажется, что SQL не может перевести этот синтаксис dplyr. Итак, мой вопрос в том, каким будет dplyr-способ достижения моего намерения, который должен выглядеть следующим образом:

 data%>%group_by(week)%>%summarise(r=mean(stock>0))

# A tibble: 3 x 2
   week     r
  <dbl> <dbl>
1    43 1    
2    44 1    
3    45 0.333
  

Я определенно хочу перенести это вычисление в базу данных, поскольку объем данных огромен. Спасибо за совет.

Ответ №1:

R автоматически преобразует logical TRUE / FALSE в 1 и 0 соответственно. Для dbplyr этого вам нужно сделать это явно с ifelse помощью .

 tbl(connection, data) %>%
  group_by(week) %>%
  summarise(r = mean(ifelse(stock > 0, 1, 0)))
  

Ответ №2:

В SQL вы можете попробовать это:

 select week, avg(case when stock > 0 then 1 else 0 end) AS r
from data
where stock > 0
group by week