我正在嘗試提取位于 SQL 資料庫中的表的子集,我得到的結果因應用過濾器的順序而異。
我需要應用三個過濾器,比如“YEAR %in% years”、“SYSTEM != 'G'”和“CODE == code”。
我嘗試將所有三個條件都放入 SQL 陳述句中:
table1 <- dbGetQuery(
conn = connection,
statement = paste0("SELECT * FROM database WHERE YEAR IN (",
paste0(years, collapse = ","), ") AND SYSTEM != 'G'" AND CODE = ", code))
但我得到的輸出是一張空桌子。
然后我嘗試將兩個條件放入陳述句中,然后使用第三個條件過濾輸出:
table2 <- dbGetQuery(
conn = connection,
statement = paste0("SELECT * FROM database WHERE YEAR IN (",
paste0(years, collapse = ","), ") AND SYSTEM != 'G'")) %>%
filter(CODE == code)
table3 <- dbGetQuery(
conn = connection,
statement = paste0("SELECT * FROM database WHERE SYSTEM != 'G' AND CODE = ", code)) %>%
filter(YEAR %in% years)
結果,table2 包含 914 行,而 table3 包含 184 行,即使結果應該完全相同。
我希望三個代碼塊中的每一個的結果都是相同的,所以我對問題可能是什么有點迷茫。
uj5u.com熱心網友回復:
查詢的引數化(且更安全)版本:
years <- 2022:2024
qry <- paste("SELECT * FROM database WHERE YEAR IN (",
paste(rep("?", length(years)), collapse = ","),
") AND SYSTEM != 'G' AND CODE = ?")
qry
# [1] "SELECT * FROM database WHERE YEAR IN ( ?,?,? ) AND SYSTEM != 'G' AND CODE = ?"
table <- dbGetQuery(conn = connection, statement = qry, params = c(years, list(code)))
可能會更進一步,并引數化'G'查詢中的常量。如果它總是'G',那么你應該沒問題,但如果這是外部確定的,那么它也應該被引數化。
請注意,?查詢中的對齊方式必須與串列中的資料完全對齊params=。如果需要在 SQL 查詢中多次使用同一個變數,那么它必須params以正確的順序出現在串列中多次,并與要系結的所有其他引數一起使用。該params=串列不能包含未使用的值。雖然所有這些聽起來可能過于約束和/或復雜,但它確實是為了保護查詢并且是值得的。由于 ANSI 或未參考的空格或類似的原因,我有太多次(非引數化)查詢神秘地中斷而沒有明確的線索。(幸運的是,它總是只會破壞查詢,而不會破壞表。)
uj5u.com熱心網友回復:
我同意 charlieface 的觀點,理想情況下您應該使用引數化查詢,但暫時試試這個:
# If CODE is varchar: code => character scalar
code <- '0001'
# Try this: table1 => data.frame
table1 <- dbGetQuery(
conn = connection,
statement = paste0(
"SELECT * FROM database WHERE YEAR IN (",
paste0(
years,
collapse = ","
),
") AND SYSTEM != 'G' AND CODE = '",
code,
"'"
)
)
# If CODE is an integer: code => integer scalar
code <- 1
# Try this: table1 => data.frame
table1 <- dbGetQuery(
conn = connection,
statement = paste0(
"SELECT * FROM database WHERE YEAR IN (",
paste0(
years,
collapse = ","
),
") AND SYSTEM != 'G' AND CODE = '",
code,
"'"
)
)
虛擬輸入資料:
# Generate some dummy data: years => integer vector
years <- seq(from = 2000, to = 2022, by = 1)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/489849.html
下一篇:按值按唯一記錄匯總
