我有一個資料庫范圍來僅過濾ProxyConfig特定Proxy和environment.
這是適用于 MySQL、PostgreSQL 和 Oracle 的原始 SQL:
class ProxyConfig < ApplicationRecord
...
scope :current_versions, -> do
where %(NOT EXISTS (
SELECT 1 FROM proxy_configs pc
WHERE proxy_configs.environment = environment
AND proxy_configs.proxy_id = proxy_id
AND proxy_configs.version < version
))
end
...
end
您可以在我的baby_squeel 問題中找到一個簡單的測驗用例。
但我發現不直接使用 SQL 更好。我花了很多時間嘗試不同的方法以 Rails 方式撰寫它,但無濟于事。我找到了通用 Rails 和 baby_squeel 示例,但它們總是涉及不同的表。
PS 以前的版本使用過joins,但速度非常慢,而且會弄亂一些查詢。例如#count產生了一個 SQL 語法錯誤。所以我對使用其他方法不是很開放。相反,我更喜歡知道如何準確地實作這個查詢。盡管我至少很想看到其他簡單的解決方案。
PPS 關于直接 SQL 就可以的問題。在這種情況下,大多數情況下是的。也許所有的 RDBMS 都能理解這個參考。如果需要比較text欄位,盡管這需要 Oracle 上的特殊功能。在 Postgres 上,不區分大小寫LIKE的是ILIKE. 可以自動處理Arel。在原始 SQL 中,不同的 RDBMS 需要不同的字串。
uj5u.com熱心網友回復:
這實際上不是您可以單獨使用 ActiveRecord 查詢介面構建的查詢。不過,它可以通過少量的 Arel 來完成:
class ProxyConfig < ApplicationRecord
def self.current_versions
pc = arel_table.alias("pc")
where(
unscoped.select(1)
.where(pc[:environment].eq(arel_table[:environment]))
.where(pc[:proxy_id].eq(arel_table[:proxy_id]))
.where(pc[:version].gt(arel_table[:version]))
.from(pc)
.arel.exists.not
)
end
end
生成的 SQL 并不相同,但我認為它在功能上應該是等效的。
SELECT "proxy_configs".* FROM "proxy_configs"
WHERE NOT (
EXISTS (
SELECT 1 FROM "proxy_configs" "pc"
WHERE "pc"."environment" = "proxy_configs"."environment"
AND "pc"."proxy_id" = "proxy_configs"."proxy_id"
AND "pc"."version" > "proxy_configs"."version"
)
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/452370.html
標籤:sql 轨道上的红宝石 rails-activerecord 数据库管理系统 不存在
上一篇:PGSearchGem--是否可以通過:against元素進行分組/加權?
下一篇:從rails5遷移到rails6
