R, SQL-запрос в течение цикла - PullRequest
0 голосов
/ 21 марта 2019

У меня есть список, который содержит клиентов и их ID.Это выглядит как показано ниже:

customers_id <- list(x = John(1,2,3), Rick = c(4), Sam = c(5,6))

и база данных, которая похожа на приведенную ниже и вызывает 'db'

date        id   value
2017-05-12  1      51 
2017-05-13  2      3  
2017-05-14  3      217
2017-05-15  1      12
2017-05-16  2      98
2017-05-17  3      123
2017-05-18  1      78
2017-05-19  2      36
2017-05-20  4      178
2017-05-18  5      728
2017-05-19  6      336
2017-05-20  4      718
2017-05-18  5      758
2017-05-19  6      366
2017-05-20  4      787

Я пытался создать цикл for, но не смогвыяснить правильное решение.Я думаю, что в цикле должен быть запрос, который будет принимать правильный идентификатор и сумму значений для идентификатора

corect_values <- paste(" SELECT date, id, SUM(value) FROM db WHERE id = '", id, "' ")

Так что у меня есть две проблемы: как поместить запрос в цикл for и как написать sqlзапрос, который будет учитывать все идентификаторы для клиента.

Результат должен быть похож на следующий:

John  618
Rick  1683
Sam   2188

У вас есть идеи, как его можно решить?Спасибо за любую помощь!

Ответы [ 5 ]

1 голос
/ 21 марта 2019

Предполагая, что у вас есть data.frame с именами и идентификаторами клиентов, например ...

customers_id <- data.frame(Names = c("John", "John", "John", "Rick", "Sam", "Sam"),
                           id = c(1:6))

Запросите все идентификаторы и значения из db ... допустим, теперь это назначено для df

SELECT id, value FROM db

Теперь вы можете left_join для ваших имен, сгруппировать их и суммировать значение.

library(dplyr)

df <- left_join (df, customers_id, by = "id")

result <- df %>% 
  group_by(Names) %>% 
  summarise(value = sum(value))
0 голосов
/ 21 марта 2019

Если вам действительно нужно использовать цикл for, чтобы выполнить запрос только для определенных клиентов, то вы можете сделать:

for (i in 1:length(customers_id)) {

  sql_q <- paste0("SELECT '", names(customers_id)[i], "' AS customer, sum(value) AS value FROM db WHERE id IN (", paste(customers_id[[i]], collapse = ", "), ")")

}

sql_q возвращает

[1] "SELECT 'John' AS customer, sum(value) AS value FROM db WHERE id IN (1, 2, 3)"
[1] "SELECT 'Rick' AS customer, sum(value) AS value FROM db WHERE id IN (4)"
[1] "SELECT 'Sam' AS customer, sum(value) AS value FROM db WHERE id IN (5, 6)"

Затем просто добавьтеданные, чтобы получить ваш результат, например

# Example Data given
customers_id <- list(John = c(1,2,3), Rick = c(4), Sam = c(5,6))

# Assuming you have your db connection setup in 'con'
sql_list <- list()
for (i in 1:length(customers_id)) {

  sql_q <- paste0("SELECT '", names(customers_id)[i], "' AS customer, sum(value) AS value FROM db WHERE id IN (", paste(customers_id[[i]], collapse = ", "), ")")
  sql_d <- sqlQuery(con, sql_q)
  sql_list[[i]] <- sql_d

}

combined_d <- do.call("rbind", sql_list)
0 голосов
/ 21 марта 2019

Я постараюсь описать как можно лучше: когда у вас есть 2 таблицы, например: (давайте возьмем ваши таблицы)

Table_A) ID, user_name

Table_B) ID, date, user_id(matched to the table above as a foreign key), value

вы можете сделать запрос следующим образом:

SELECT Table_A.user_name, sum(Table_B.value)
FROM Table_A join Table_B on Table_a.ID = Table_B.user_id
GROUP BY Table_A.ID  

Этот запрос будет суммировать все значения для всех ваших пользователей.Для каждого пользователя будет показана только одна запись со всеми суммированными значениями

0 голосов
/ 21 марта 2019

Этот выбор доставляет желаемые результаты?

customer_id = sample(c(1:6), 10, replace = T) # just some dummy-user ids as an example

customer_id = paste0("'", customer_id, "'")
customer_id = paste(customer_id, collapse =  ", ")

corect_values = paste0("SELECT sum(value) FROM db where id IN (", customer_id, ") GROUP BY id")

ofc это не так, так как вы не хотите группировать по идентификатору, но по имени и имени охватывает более одного идентификатора.

возможно, это решит проблему.Недостаток: вы все равно должны сделать запрос на каждое имя.Поэтому, даже если следующий код работает, я думаю, что было бы лучше создать справочную таблицу в вашей базе данных, чтобы объединить имя и идентификатор, как @Andrei Fiordean предложил в комментариях.

select_this <- function(temp_ids)
{

  temp_ids = paste0("'", temp_ids, "'")
  temp_ids = paste(temp_ids, collapse =  ", ")
  corect_values = paste0("SELECT sum(value) FROM db where id IN (", temp_ids, ")")
  # results = request select from db here
  return(results)
}

customers_id <- list("John" = c(1,2,3), "Rick" = c(4), "Sam" = c(5,6))
sapply(customers_id, select_this)
0 голосов
/ 21 марта 2019

Этот код для суммирования

ВЫБЕРИТЕ СУММУ (значения) всего ОТ БД, ГДЕ customer_id = id;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...