将您的描述直接转译为 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 null
andwhere path is null
组件。我不知道该怎么做。
事实上,我倾向于放弃 ActiveRecord。我发现 ActiveRecord 对于我所做的大多数复杂的事情都相当麻烦,而且几乎不像 SQL 那样富有表现力。这适用于我曾经使用过的每个 ORM,因此问题并不特定于 ActiveRecord。