在PostgreSQL中选择带有DISTINCT的列

时间:2011-02-15 20:46:27

标签: ruby-on-rails postgresql activerecord

我正在从数据库查询公交车站,我希望每个公交线路/方向只返回1站。这个查询只是这样:

Stop.select("DISTINCT line_id, direction")

除了它不会给我任何其他属性而不是那些2.除了idline_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个查询中拥有它并让它返回所有属性?

2 个答案:

答案 0 :(得分:27)

Stop.select("DISTINCT ON (line_id, direction) *")

答案 1 :(得分:3)

不是那么快 - 另一个答案选择stop_id random

这就是为什么你的问题毫无意义。我们可以拉出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(或其他任何东西)绝望。