我正在从数据库查询公交车站,我希望每个公交线路/方向只返回1站。这个查询只是这样:
Stop.select("DISTINCT line_id, direction")
除了它不会给我任何其他属性而不是那些2.除了id
和line_id
之外,我尝试了几个其他查询让它返回direction
字段(理想情况下它会返回所有列),没有运气:
Stop.select("DISTINCT line_id, direction, id")
和
Stop.select("DISTINCT(line_id || '-' || direction), id")
在这两种情况下,查询都会丢失其distinct子句,并返回所有行。
一些很棒的家伙帮我出去并建议使用子查询让它返回所有ID:
Stop.find_by_sql("SELECT DISTINCT a1.line_id, a1.direction, (SELECT a2.id from stops a2 where a2.line_id = a1.line_id AND a2.direction = a1.direction ORDER BY a2.id ASC LIMIT 1) as id FROM stops a1
然后,我可以提取所有ID并执行第二个查询以获取每个停靠点的完整属性。
有没有办法在1个查询中拥有它并让它返回所有属性?
答案 0 :(得分:27)
Stop.select("DISTINCT ON (line_id, direction) *")
答案 1 :(得分:3)
这就是为什么你的问题毫无意义。我们可以拉出stop_ids并具有明显的line_id和方向。但我们不知道为什么我们有stop_id。
create temp table test( line_id integer, direction char(1), stop_id integer);
insert into test values
(1, 'N', 1),
(1, 'N', 2),
(1, 'S', 1),
(1, 'S', 2),
(2, 'N', 1),
(2, 'N', 2),
(2, 'S', 1),
(2, 'S', 2)
;
select distinct on (line_id, direction) * from test;
-- do this again but will reverse the order of stop_ids
-- could it possible change our Robust Query?!!!
drop table test;
create temp table test(line_id integer,direction char(1),stop_id integer);
insert into test values
(1, 'N', 2),
(1, 'N', 1),
(1, 'S', 2),
(1, 'S', 1),
(2, 'N', 2),
(2, 'N', 1),
(2, 'S', 2),
(2, 'S', 1)
;
select distinct on (line_id, direction) * from test;
首先选择:
line_id | direction | stop_id
---------+-----------+---------
1 | N | 1
1 | S | 1
2 | N | 1
2 | S | 1
第二次选择:
line_id | direction | stop_id
---------+-----------+---------
1 | N | 2
1 | S | 2
2 | N | 2
2 | S | 2
所以我们离开了没有分组stop_id,但我们无法保证为什么我们得到了那个 我们做到了。我们所知道的是这是有效的stop_id。任何更新,插入和其他 没有RDMS可以保证的东西可以围绕行的物理顺序进行更改。
这就是我在最高评论中的含义。没有已知的理由将一个stop_id拉到另一个上,但不知怎的,你需要这个stop_id(或其他任何东西)绝望。