将您的描述直接转译为 SQL 如下所示:
select name, path, value
from (
select name, path, value,
row_number() over (partition by path order by value desc) as r
from your_table
where path is not null
) as dt
where r = 1
union all
select name, path, value
from your_table
where path is null
您可以将其包装在 a 中find_by_sql,然后将您的对象从另一侧取出。
该查询的工作方式如下:
row_number 窗口函数允许我们按 对行进行分组,path按 对每个组进行排序value,然后对每个组中的行进行编号。在里面玩一下 SQL psql,你会看到它是如何工作的,还有其他可用的窗口函数可以让你做各种美妙的事情。
- 您将 NULL
path值与非 NULL 分开处理path,因此path is not null在内部查询中。
path我们可以通过从派生表中选择行号为 1(即where r = 1)的行来剥离每个组中的第一行。
- 部分查询很容易处理
path is null行的处理。
- UNION 用于将查询的结果集连接在一起。
我想不出任何方法来使用 ActiveRecord 构造这样的查询,也想不出任何方法将这样的查询与 ActiveRecord 的作用域机制集成。如果您可以轻松地仅访问 an 的 WHERE 组件,ActiveRecord::Relation那么您可以使用范围链的 WHERE 组件来扩充该查询的where path is not nullandwhere path is null组件。我不知道该怎么做。
事实上,我倾向于放弃 ActiveRecord。我发现 ActiveRecord 对于我所做的大多数复杂的事情都相当麻烦,而且几乎不像 SQL 那样富有表现力。这适用于我曾经使用过的每个 ORM,因此问题并不特定于 ActiveRecord。