自定义查询来获取表的所有条目,并且仅包含基于特定列的多个重复项中的第一个

问题描述 投票:0回答:1

我有一个位置模型,表格看起来像

id 名字 ip_地址 创建于 更新于
0 默认 0 0.0.0.0/0 2021-11-08 11:54:26.822623 2021-11-08 11:54:26.822623
1 管理员 1 10.108.150.143 2021-11-08 11:54:26.82885 2021-11-08 11:54:26.82885
2 V122 122 10.108.150.122 2021-11-08 11:54:26.82885 2021-11-08 11:54:26.82885
3 V123 123 10.108.150.123 2021-11-08 11:54:26.82885 2021-11-08 11:54:26.82885
4 V124 124 10.108.150.124 2021-11-08 11:54:26.82885 2021-11-08 11:54:26.82885
5 V122 122 10.108.150.122 2021-11-08 11:54:26.82885 2021-11-08 11:54:26.82885
6 V125 122 10.108.150.125 2021-11-08 11:54:26.82885 2021-11-08 11:54:26.82885

我在位置模型中的方法

   def self.find_all_non_duplicate
     return self.find(:all, :conditions => "id <> 1")
   end

我想获取位置表的所有条目,除了 id = 1 的条目,并且该条目仅包含基于列 ip_address 的许多重复项中的第一个条目。

因为 id = 2 和 id = 5 的 ip_address 是重复的。我想保留许多重复项中的第一个条目,即 id = 2。 预期结果是

id名字0默认V122V123V124V125id为1和5的条目将被忽略
ip_地址 创建于 更新于
0 0.0.0.0/0 2021-11-08 11:54:26.822623 2021-11-08 11:54:26.822623 2
122 10.108.150.122 2021-11-08 11:54:26.82885 2021-11-08 11:54:26.82885 3
123 10.108.150.123 2021-11-08 11:54:26.82885 2021-11-08 11:54:26.82885 4
124 10.108.150.124 2021-11-08 11:54:26.82885 2021-11-08 11:54:26.82885 6
122 10.108.150.125 2021-11-08 11:54:26.82885 2021-11-08 11:54:26.82885

您需要的是最近

这里
ruby-on-rails postgresql ruby-on-rails-3 activerecord
1个回答
3
投票

distinct on

,但
尚未合并,正如@engineersmnky所指出的那样。在原始 SQL 形式中,它看起来像这样: select distinct on (ip_address) * from test where id<>1 order by ip_address,created_at; 这将转化为 RoR

self.where("id <> 1").distinct_on(:ip_address)

或者,直到新功能被接受:

self.where("id <> 1").select("distinct on (ip_address) *")

完整的数据库端测试:

drop table if exists test cascade;
create table test (
    id serial primary key,
    name text,
    vin integer,
    ip_address inet,
    created_at timestamp,
    updated_at timestamp);
insert into test 
(id,name,vin,ip_address,created_at,updated_at)
values
(0,'default', 0,'0.0.0.0/0'::inet,'2021-11-08 11:54:26.822623'::timestamp,'2021-11-08 11:54:26.822623'::timestamp),
(1,'admin',   1,'10.108.150.143'::inet,'2021-11-08 11:54:26.82885'::timestamp,'2021-11-08 11:54:26.82885'::timestamp),
(2,'V122',    122,'10.108.150.122'::inet,'2021-11-08 11:54:26.82885'::timestamp,'2021-11-08 11:54:26.82885'::timestamp),
(3,'V123',    123,'10.108.150.123'::inet,'2021-11-08 11:54:26.82885'::timestamp,'2021-11-08 11:54:26.82885'::timestamp),
(4,'V124',    124,'10.108.150.124'::inet,'2021-11-08 11:54:26.82885'::timestamp,'2021-11-08 11:54:26.82885'::timestamp),
(5,'V122',    122,'10.108.150.122'::inet,'2021-11-08 11:54:26.82885'::timestamp,'2021-11-08 11:54:26.82885'::timestamp),
(6,'V125',    122,'10.108.150.125'::inet,'2021-11-08 11:54:26.82885'::timestamp,'2021-11-08 11:54:26.82885'::timestamp);

select distinct on (ip_address) * 
from test where id<>1 
order by ip_address,created_at;
-- id |  name   | vin |   ip_address   |         created_at         |         updated_at
------+---------+-----+----------------+----------------------------+----------------------------
--  0 | default |   0 | 0.0.0.0/0      | 2021-11-08 11:54:26.822623 | 2021-11-08 11:54:26.822623
--  2 | V122    | 122 | 10.108.150.122 | 2021-11-08 11:54:26.82885  | 2021-11-08 11:54:26.82885
--  3 | V123    | 123 | 10.108.150.123 | 2021-11-08 11:54:26.82885  | 2021-11-08 11:54:26.82885
--  4 | V124    | 124 | 10.108.150.124 | 2021-11-08 11:54:26.82885  | 2021-11-08 11:54:26.82885
--  6 | V125    | 122 | 10.108.150.125 | 2021-11-08 11:54:26.82885  | 2021-11-08 11:54:26.82885
--(5 rows)

© www.soinside.com 2019 - 2024. All rights reserved.