#mysql #sql #r #for-loop
#mysql #sql #r #for-цикл
Вопрос:
У меня есть список, содержащий клиентов и их 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-запрос, который будет учитывать все идентификаторы для customer.
Результат должен быть похож на приведенный ниже:
John 618
Rick 1683
Sam 2188
У вас есть какие-либо идеи, как это можно решить?
Спасибо за любую помощь!
Комментарии:
1. добавьте «группировать по идентификатору», это будет группировать по идентификатору. (или вы можете выбрать с помощью таблицы customer)
2. таким образом, в основном к нескольким идентификаторам привязан один и тот же пользователь (например, John привязан к идентификатору 1,2,3)? и если да, то почему? создайте один идентификатор для одного имени. Я мог бы показать вам в ответе запрос, который будет суммироваться для каждого из идентификаторов, если вы хотите, чтобы я
3. Я думаю, вам не нужен цикл здесь. Вместо того, чтобы перебирать каждый идентификатор самостоятельно, вы могли бы выбрать все идентификаторы сразу, используя «… ГДЕ id В («, id, «) ….». возможно, вам придется обернуть каждый отдельный id-номер в vector id внутри ‘ ‘, чтобы это сработало.
4. Вы могли бы выбрать идентификатор и значение из базы данных, затем в R объединить имена по идентификатору и выполнить сумму, сгруппированную по имени? Или вы специально пытаетесь сделать это с помощью запроса?
5. проблема в том, что у меня более 100 клиентов, и у них от 1 до 200 идентификаторов, поэтому я не уверен, как я мог бы использовать один идентификатор для одного имени @AndreiFiordean
Ответ №1:
Предполагая, что у вас есть data.frame с именами клиентов и идентификаторами, подобными этому…
customers_id <- data.frame(Names = c("John", "John", "John", "Rick", "Sam", "Sam"),
id = c(1:6))
Запросите весь идентификатор и значение из базы данных … допустим, теперь это присвоено 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))
Комментарии:
1. Я пытался использовать ваше решение, но я получил эту ошибку «Ошибка в UseMethod («group_by_»): нет применимого метода для ‘group_by_’, примененного к объекту класса «функция»»
Ответ №2:
Этот код для суммирования
ВЫБЕРИТЕ СУММУ (значения) total Из базы данных, ГДЕ customers_id = идентификатор;
Ответ №3:
Я постараюсь описать как можно лучше: когда у вас есть 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
Этот запрос просуммирует все значения для всех пользователей, которые у вас есть.
Он покажет только одну запись для каждого пользователя со всеми суммированными значениями
Комментарии:
1. Насколько я понимаю его вопрос, похоже, что таблица A не существует в его базе данных?
2. я так думаю, возможно, что таблица A не существует в его базе данных, и именно поэтому его работа намного сложнее
3. Вы правы, он не завершается как db. Тип — это список
4. ваша жизнь была бы намного проще, если бы вы просто создали другую таблицу и связали ее с вашей целевой таблицей, это мой совет для вас, сэр
5. Не могли бы вы, пожалуйста, исправить свой пример списка идентификаторов? или даже
dput()
ваш список идентификаторов клиентов?
Ответ №4:
Обеспечивает ли этот выбор желаемые результаты?
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 это не так, поскольку вы не хотите группировать по идентификатору, но по имени, а имя охватывает не только один идентификатор.
возможно, это может решить проблему. Недостаток в том, что вам все равно придется делать запрос для каждого имени. Итак, даже если следующий код работает, я думаю, все равно было бы лучше создать справочную таблицу в вашей базе данных, чтобы объединить name и id, как предложил @Andrey 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)
Ответ №5:
Если вам действительно нужно использовать цикл 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)