繁体   English   中英

基于与数组列比较的 Select 关联记录

[英]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 ,我正在寻找一个返回与该车辆关联的所有用户的查询,

  1. 其中 vehicle_ids 包含车辆的 id
  2. 其中 vehicle_ids 只有车辆的 id(即单个元素)

我们可以使用ANYALL结构(更多细节在这里Row and Array Comparisons

使用“任何”

http://sqlfiddle.com/#!17/ec886/21

对于第一种情况,我们需要返回与搜索查询(以及其他)表示的车辆相关联的用户,我们可以使用 ANY。 因此,当提供v2作为车辆名称时,以下查询将返回名称为u2u3的用户行

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM