PostgreSQL:根据其他 table 中关联记录的最大值查找一个 table 中的行
PostgreSQL: Find the rows in one table based on the maximum of associated records in other tables
我有下表
vehicles - id, name
vehicle_settings - id, settings, vehicle_id, company_id, updated_at, updated_by
vehicle_licenses - id, license_number, vehicle_id, company_id, updated_at, updated_by
users - id, name, email
一辆车可以在 vehicle_settings
中有多个条目,在 vehicle_licenses
中可以有多个条目
车辆可能没有 vehicle_settings 或车辆牌照。
现在,我需要具有上次更新车辆设置或许可证的用户的所有车辆的列表。我还应该能够使用车辆 ID 过滤列表,并能够计算符合过滤条件的所有车辆的数量。
所以,我尝试了以下查询
SELECT DISTINCT ON (v.id) v.id,
(
SELECT
JSON_BUILD_OBJECT(
'id', u.id,
'name', u.name,
'email', u.email
)
FROM users u WHERE u.id=updates.updated_by AND updates.updated_at = MAX(updates.updated_at)
) AS updated_by,
MAX(updates.updated_at) AS updated_at,
COUNT(*) over ()
FROM vehicles v
LEFT JOIN LATERAL(
select foo.updated_by,foo.updated_at FROM (
select vs.updated_by,vs.updated_at from vehicle_settings vs WHERE vs.vehicle_id = v.id
UNION
select vl.updated_by,vl.updated_at from vehicle_licenses vl WHERE vl.vehicle_id = v.id
) AS foo order by updated_at desc LIMIT 1
) AS updates ON TRUE
WHERE v.id 'c4ced8df-c93f-45e8-806f-f7d5f20d9d75'
GROUP BY v.id, updates.updated_by,updates.updated_at ;
此查询运行良好,但计数具有误导性。我得到的计数数量比车辆数量多。我想也许它也需要来自 LEFT LATERAL JOIN
的条目。
SELECT v.*, u.*,
COUNT(*) FILTER (WHERE v.id = 'c4ced8df-c93f-45e8-806f-f7d5f20d9d75') OVER ()
FROM vehicles AS v
LEFT JOIN (SELECT DISTINCT ON (vehicle_id)
vehicle_id, updated_by
FROM (SELECT vehicle_id, updated_by, updated_at
FROM vehicle_settings
UNION ALL
SELECT vehicle_id, updated_by, updated_at
FROM vehicle_licenses) AS x
ORDER BY vehicle_id, updated_at DESC) AS vu
ON v.id = vu.vehicle_id
LEFT JOIN users AS u
ON vu.updated_by = u.id;
我有下表
vehicles - id, name
vehicle_settings - id, settings, vehicle_id, company_id, updated_at, updated_by
vehicle_licenses - id, license_number, vehicle_id, company_id, updated_at, updated_by
users - id, name, email
一辆车可以在 vehicle_settings
中有多个条目,在 vehicle_licenses
中可以有多个条目
车辆可能没有 vehicle_settings 或车辆牌照。
现在,我需要具有上次更新车辆设置或许可证的用户的所有车辆的列表。我还应该能够使用车辆 ID 过滤列表,并能够计算符合过滤条件的所有车辆的数量。
所以,我尝试了以下查询
SELECT DISTINCT ON (v.id) v.id,
(
SELECT
JSON_BUILD_OBJECT(
'id', u.id,
'name', u.name,
'email', u.email
)
FROM users u WHERE u.id=updates.updated_by AND updates.updated_at = MAX(updates.updated_at)
) AS updated_by,
MAX(updates.updated_at) AS updated_at,
COUNT(*) over ()
FROM vehicles v
LEFT JOIN LATERAL(
select foo.updated_by,foo.updated_at FROM (
select vs.updated_by,vs.updated_at from vehicle_settings vs WHERE vs.vehicle_id = v.id
UNION
select vl.updated_by,vl.updated_at from vehicle_licenses vl WHERE vl.vehicle_id = v.id
) AS foo order by updated_at desc LIMIT 1
) AS updates ON TRUE
WHERE v.id 'c4ced8df-c93f-45e8-806f-f7d5f20d9d75'
GROUP BY v.id, updates.updated_by,updates.updated_at ;
此查询运行良好,但计数具有误导性。我得到的计数数量比车辆数量多。我想也许它也需要来自 LEFT LATERAL JOIN
的条目。
SELECT v.*, u.*,
COUNT(*) FILTER (WHERE v.id = 'c4ced8df-c93f-45e8-806f-f7d5f20d9d75') OVER ()
FROM vehicles AS v
LEFT JOIN (SELECT DISTINCT ON (vehicle_id)
vehicle_id, updated_by
FROM (SELECT vehicle_id, updated_by, updated_at
FROM vehicle_settings
UNION ALL
SELECT vehicle_id, updated_by, updated_at
FROM vehicle_licenses) AS x
ORDER BY vehicle_id, updated_at DESC) AS vu
ON v.id = vu.vehicle_id
LEFT JOIN users AS u
ON vu.updated_by = u.id;