我有一个表transactions
,可能包含重复项(对我们来说,副本是Transaction
,具有相同的account_id
,date
和{{1 }})。
我的英语功能要求是“我希望看到所有交易中存在多个具有相同account_id,日期和金额的交易”。
暂时放弃AREL,我在SQL中制作了类似的东西:
amount
我正在使用Rails 3.2.x和Postgres。
最初,我在AREL尝试了这个:
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
但是这给了我关于聚合函数的SQL错误:
Transaction.group(:account_id, :date, :amount).having("count(id) > 1")
..这令人沮丧,因为我不想要group by子句中的ID - 整点是我希望在检查dupes时忽略ID。
我很感激,如果有人能指出我正确的AREL方向,我需要将其作为范围 - PG::Error: ERROR: column "transactions.id" must appear in the GROUP BY clause or be used in an aggregate function
在您需要记录时非常好,但我正在尝试创建一个ActiveAdmin范围 - 它不喜欢数组。
答案 0 :(得分:1)
您可以在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
两种方式都很昂贵,记忆力很强。祝你好运。
答案 1 :(得分:1)
也许像
def similar
table = self.class.arel_table
conditions = %w[ date amount ].map { |field| table[field].eq send(field) }.map &:to_sql
self.class.where "id != #{ id } AND #{ conditions.join ' AND ' }"
end
答案 2 :(得分:1)
如果您愿意将结果以多行的形式返回给您,您可以尝试以下方式:
select account_id, amount, day, group_concat(id)
from purchases
group by account_id, amount, day having count(id) > 1;
这将返回一个结果集,其中每行包含给定帐户,日期和金额的重复项。