在Postgresql中

时间:2018-04-25 16:49:25

标签: sql postgresql

这是一个复杂的问题,但我相信这里有人会在大约2分钟内知道答案,我会感到愚蠢。

我所拥有的是路线,交货名称和交货时间表。让我们说它看起来像这样:

+------------+---------------+-------+
| ROUTE CODE |     NAME      | TIME  |
+------------+---------------+-------+
| A          | McDonald's    | 5:30  |
| A          | Arby's        | 5:45  |
| A          | Burger King   | 6:00  |
| A          | Wendy's       | 6:30  |
| B          | Arby's        | 7:45  |
| B          | Arby's        | 7:45  |
| B          | Burger King   | 8:30  |
| B          | McDonald's    | 9:00  |
| C          | Wendy's       | 9:30  |
| C          | Lion's Choice | 8:15  |
| C          | Steak N Shake | 9:50  |
| C          | Hardee's      | 10:30 |
+------------+---------------+-------+

我希望结果返回的是这样的:

+------------+---------------+------+
| ROUTE CODE |     NAME      | TIME |
+------------+---------------+------+
| A          | McDonald's    | 5:30 |
| B          | Arby's        | 7:45 |
| C          | Lion's Choice | 8:15 |
+------------+---------------+------+

所以我想要的是每个路线代码的最短时间名称。

我编写了一个查询,让我大部分都在那里(如果您认为有更有效的方法,可以随意改进此查询):

SELECT main1.route_code, main1.first_stop, main2.name
FROM
  (SELECT route_code, min(time) as first_stop FROM table1 WHERE date = yesterday GROUP BY route_code) main1 
  JOIN 
  (SELECT route_code, name, time FROM table1 WHERE date = yesterday) main2 
  ON main1.route_code = main2.route_code and main1.first_stop = main2.time

这是我需要你帮助的地方。如果我有相同的时间,它会返回该行两次,我只想要一次。因此,例如,上述查询将返回Arby的路由代码" B"两次,因为它有相同的时间。我只想看到这一次,我不想再多次从路线上看到任何东西。

任何人都可以帮助我吗?非常感谢!

2 个答案:

答案 0 :(得分:2)

在Postgres中,您可以使用distinct on

select distinct on (route_code) t.*
from table1 t
order by route_code, time asc;

这可能是Postgres中最快的方法。为了提高性能,建议使用(route_code, time)的索引。

答案 1 :(得分:0)

这是另一种让你的结果可能或可能不会更好的方法:

SELECT route_name, time, name FROM 
(SELECT *, ROW_NUMBER() OVER (PARTITION BY route_code ORDER BY time ASC) row_num FROM table1) subq
WHERE row_num = 1;