我有一个表transactions
,它可能包含重复项(对我们来说,重复项是具有相同account_id
的Transaction
,日期
和金额
)。
我的英语功能要求是“我想查看存在超过 1 笔具有相同 account_id、日期和金额的交易的所有交易”。
暂时放弃AREL,我用SQL生成了这样的东西:
SELECT * FROM transactions t1, transactions t2
WHERE t1.id != t2.id
AND t1.date = t2.date
AND t1.amount = t2.amount
AND t1.account_id = t2.account_id
我正在使用 Rails 3.2.x 和 Postgres。
最初,我在 AREL 中尝试过:
Transaction.group(:account_id, :date, :amount).having("count(id) > 1")
但这给了我关于聚合函数的 SQL 错误:
PG::Error: ERROR: column "transactions.id" must appear in the GROUP BY clause or be used in an aggregate function
..这令人沮丧,因为我不想要在group by子句中使用ID——重点是我希望在检查重复项时忽略ID。
如果有人能指出我需要将其设为范围的 AREL 的正确方向,我将不胜感激 - 当您需要记录时,find_by_sql
非常有用,但我正在尝试创建ActiveAdmin 作用域——它不喜欢数组。
最佳答案
您可以在 ActiveRecord Transaction 模型中使用 sql 定义范围,如下所示:
scope :duplicate_transactions, where(<<-eosql.strip)
transactions.id IN (
SELECT
t1.id
FROM
transactions t1, transactions t2
WHERE
t1.id != t2.id AND
t1.date = t2.date AND
t1.amount = t2.amount AND
t1.account_id = t2.account_id
)
eosql
但是随后涉及到 id.. 可能不是您想要的,因为这是一个昂贵的查询。至少在
上创建一个非唯一索引date, amount, account_id
对于这个表。这应该可以为您节省一些全表行扫描...另一种方法是执行类似的操作
Transaction.joins(<<eosql.strip)
LEFT OUTER JOIN transactions t ON
transactions.id != t.id AND
transactions.date = t.date AND
transactions.amount = t.amount
eosql
这两种方式在内存方面都很昂贵。祝你好运。
关于ruby-on-rails-3 - 如何在 AREL 中将表与其自身连接起来以查找重复项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14993410/