如何根据字段postgres的高度值从关系中进行选择?

时间:2019-09-02 14:06:37

标签: postgresql

我有三个表格车辆,行程和componentValue,它们通过

相互关联
vehicles -> trips -> componentValues 

vehicles Table : id, ...

trips Table: id, vehicle_id, ...

componentValues Table: id, trip_id, damage, ...

并且我正试图从像这样的componentValues表中获得具有最高损坏组件的所有行程

SELECT *
 FROM (select * from trips WHERE "trips"."vehicle_id" = '7') as t
 LEFT JOIN (
    select * from "component_values"
    where trip_id = '85'
    order by damage
    desc nulls last limit 1
) as h on t.id = h.trip_id

我如何才能将行where trip_id = '85'更改为动态行,或者将行select * , (select damage from "component_values" where trip_id = trips.id order by damage desc nulls last limit 1) as h_damage, (select damage from "component_values" where trip_id = trips.id order by damage asc nulls first limit 1) as l_damage, (select component_types.name from "component_values" left join component_types on component_values.component_type_id = component_types.id where trip_id = trips.id order by damage desc nulls last limit 1) as hc_damage, (select component_types.name from "component_values" left join component_types on component_values.component_type_id = component_types.id where trip_id = trips.id order by damage asc nulls first limit 1) as lc_damage from trips WHERE trips."vehicle_id" = '7' 更改为动态行,这是我的另一种方式。

预期结果:

enter image description here

更新

我进行了一些查询以获得我想要的内容,但是如何通过不使用select语句中的子查询来改善它

handlers

2 个答案:

答案 0 :(得分:3)

我认为您想要distinct on

select distinct on (t.id) t.*, dv.damage
from trips t join
     component_values cv
     on cv.trip_id = t.id
where t.vehicle_id = 7  -- not sure if this is needed
order by t.id, cv.damage desc nulls last;

distinct on通常是Postgres中最有效的方法。您还可以使用窗口功能执行此操作:

select distinct on (t.id) t.*, cv.damage
from trips t join
     (select cv.*,
             row_number() over (partition by cv.trip_id, cv.damage desc nulls last) as seqnum
      from component_values cv
     ) cv
     on cv.trip_id = t.id and cv.seqnum = 1
where t.vehicle_id = 7;  -- not sure if this is needed

答案 1 :(得分:1)

我认为您想要横向加入。

SELECT *
 FROM (select * from trips WHERE "trips"."vehicle_id" = '7') as t
 LEFT JOIN lateral (
    select * from "component_values"
    where trip_id = t.id
    order by damage
    desc nulls last limit 1
) as h on true

尽管我认为第一个子查询没有理由,所以:

SELECT *
 FROM trips
 LEFT JOIN lateral (
    select * from "component_values"
    where trip_id = trips.id
    order by damage
    desc nulls last limit 1
) as h on true
WHERE "trips"."vehicle_id" = '7'