![](/img/trans.png)
[英]SQL: Select records based on comparison of two most recent associated records
[英]Select associated records based on comparison with array column
假设有下表的假设场景
Vehicles
+----+--------+
| id | number |
+----+--------+
| 1 | v1 |
| 2 | v2 |
| 3 | v3 |
+----+--------+
Users
+-----+------+-------------+
| id | name | vehicle_ids |
+-----+------+-------------+
| 100 | u1 | {1} |
| 200 | u2 | {1,2} |
| 300 | u3 | {2,3} |
| 400 | u4 | {} |
+-----+------+-------------+
给定车辆的number
,我正在寻找一个返回与该车辆关联的所有用户的查询,
我们可以使用ANY
和ALL
结构(更多细节在这里Row and Array Comparisons )
http://sqlfiddle.com/#!17/ec886/21
对于第一种情况,我们需要返回与搜索查询(以及其他)表示的车辆相关联的用户,我们可以使用 ANY。 因此,当提供v2
作为车辆名称时,以下查询将返回名称为u2
和u3
的用户行
SELECT "users".*
FROM "users"
WHERE (
(SELECT "vehicles"."id" FROM "vehicles" WHERE "vehicles"."number" = 'v2') =
ANY("users"."vehicle_ids")
)
您可以将"number" = 'v2'
替换为任何其他车辆名称以获取与该车辆编号关联的所有用户。
http://sqlfiddle.com/#!17/ec886/27
对于我们需要完全匹配的第二种情况,即数组中只有一个元素,我们将使用 All。 因此,以下查询将在v1
时仅返回名称为u1
的用户行
SELECT "users".*
FROM "users"
WHERE (
"users"."vehicle_ids" != '{}' and
(SELECT "vehicles"."id" FROM "vehicles" WHERE "vehicles"."number" = 'v1') = ALL("users"."vehicle_ids")
)
如果我们不使用"users"."vehicle_ids" != '{}'
那么结果也将包含用户u4
此子查询方法仅适用于单个车辆,即我们不能WHERE "vehicles"."number" in ('v2', v3)
因为子查询将返回多行并且 Postgres 将抛出错误。 如果它可以与原始问题具有相同的目的,并且它是否足够通用以支持上述用例,我们可能不得不unnest
它。
您也可以使用unnest()
:
select u.*
from users u cross join lateral
unnest(vehicle_ids) x(vehicle_id) join
vehicles v
on v.id = x.vehicle_id
where v.number = 'v2';
这是一个 db<>fiddle。
问题 #1:“其中 vehicle_ids 包含车辆的 id”
您可以使用数组上的条件连接两个表
select u.*
from users u
join vehicles v on v.id = any(u.vehicle_ids)
where v.number = 'v1';
问题 #2:“其中 vehicle_ids 仅具有车辆的 id(即单个元素)”
这可以通过从 SELECT 语句创建单个元素数组来实现
select u.*
from users u
where u.vehicle_ids = array(select v.id from vehicle v where v.number = 'v1');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.