Проверьте, существует ли запись с помощью dbplyr

Чтобы проверить, существует ли запись в таблице SQL (скажем, «Продукты»), ответ с наибольшим количеством голосов в sql - быстрый способ определить, существует ли запись, предлагает использовать

IF EXISTS (SELECT * FROM Products WHERE id = '?') 
...

Имея соединение con с базой данных SQL, есть ли способ выполнить такое действие над таблицей dplyr::tbl(con)? Можно, конечно, использовать %>% dplyr::filter(id %in% !!x), чтобы выбрать только соответствующие строки и сравнить результат с записью (здесь x). Однако это кажется неэффективным.


person FOMH    schedule 09.11.2020    source источник


Ответы (1)


Строка IF EXISTS ..., которую вы цитируете, является частью транзакционного оператора sql, а не чистого запроса, извлекающего данные из таблицы. Я не нашел способа перевести dbplyr транзакционные операторы sql, только запросы. В общем, при использовании dbplyr я бы использовал R для операторов управления, а не транзакционный sql.

То, что я бы порекомендовал вместо этого, согласуется с принятым ответом на вопрос, который вы связали:

id_to_find <- 1234
remote_table <- dplyr::tbl(db_connection, from = tbl_name)

# create query
fetched_id <- remote_table %>%
  filter(id == id_to_find) %>%
  select(id) %>%
  head(1)

# validate query
show_query(fetched_id)

# fetch result into R
fetched_id <- fetched_id %>%
  collect()

Это вернет R кадр данных 1x1, если идентификатор существует, или кадр данных 0x1, если он не существует. Затем это можно проверить с помощью if(nrow(fetched_id) == 1){....

В качестве альтернативы вы можете взглянуть на dbExecute в пакете DBI. Это позволяет передать текстовую строку из R в SQL. Таким образом, вы можете создать транзакционный оператор sql в R и передать его в базу данных без dbplyr.

Последнее замечание: у dbplyr есть перевод на EXISTS для сервера sql. Это происходит, если вы выполняете полусоединение. Так что, если ваше приложение может быть написано с полусоединением, вы можете подойти к проблеме таким образом.

person Simon.S.A.    schedule 10.11.2020