如何获取两个值都可以在两列中的行?
How to get row where both values could be in two columns?
我有一个table
-- Table Definition ----------------------------------------------
CREATE TABLE rooms (
id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
user_id_one uuid NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
user_id_two uuid NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
create_time timestamp with time zone NOT NULL DEFAULT now()
);
-- Indices -------------------------------------------------------
CREATE UNIQUE INDEX room_pkey ON rooms(id int4_ops);
我想用一对特定的 user_id
得到 rooms.id
。
执行此操作的最佳方法是什么?
1.
SELECT r.id
FROM rooms r
WHERE '9af0521d-f999-42e8-aafd-4bf2d839eafb' in (user_id_one, user_id_two)
AND '0ff77b22-62f9-44ce-8f2e-7e85726dbb3e' in (user_id_one, user_id_two)
SELECT r.id
FROM rooms r
WHERE user_id_one in ('9af0521d-f999-42e8-aafd-4bf2d839eafb', '0ff77b22-62f9-44ce-8f2e-7e85726dbb3e')
AND user_id_two in ('9af0521d-f999-42e8-aafd-4bf2d839eafb', '0ff77b22-62f9-44ce-8f2e-7e85726dbb3e')
SELECT r.id
FROM rooms r
WHERE (
(user_id_one = '9af0521d-f999-42e8-aafd-4bf2d839eafb'
AND user_id_two = '0ff77b22-62f9-44ce-8f2e-7e85726dbb3e')
OR
(user_id_one = '0ff77b22-62f9-44ce-8f2e-7e85726dbb3e'
AND user_id_two = '9af0521d-f999-42e8-aafd-4bf2d839eafb')
)
或者完全不同的东西?
假设这两个用户 ID 永远不会有相同的值,那么您的所有三个版本都是有效的。我可以建议另一个版本,也许比您已有的版本更简洁:
SELECT id
FROM rooms r
WHERE LEAST(user_id_one, user_id_two) = '0ff77b22-62f9-44ce-8f2e-7e85726dbb3e' AND
GREATEST(user_id_one, user_id_two) = '9af0521d-f999-42e8-aafd-4bf2d839eafb';
上面least/greatest的做法是一箭双雕。无论匹配的 ID 集以何种顺序出现,上述方法都有效,因为它断言较小的 UUID 显示为一个用户 ID,较大的 UUID 显示为另一个用户 ID。
您可以通过数组进行比较:
WHERE ARRAY [user_id_one,user_id_two] @> ARRAY ['9af0521d-f999-42e8-aafd-4bf2d839eafb','0ff77b22-62f9-44ce-8f2e-7e85726dbb3e']
这里是 dbfiddle 示例
我会更改您的第二个查询,以便您只传递一次您想要的一对 uuid:
SELECT id
FROM rooms
WHERE (?, ?) IN ((user_id_one, user_id_two), (user_id_two, user_id_one));
我有一个table
-- Table Definition ----------------------------------------------
CREATE TABLE rooms (
id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
user_id_one uuid NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
user_id_two uuid NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
create_time timestamp with time zone NOT NULL DEFAULT now()
);
-- Indices -------------------------------------------------------
CREATE UNIQUE INDEX room_pkey ON rooms(id int4_ops);
我想用一对特定的 user_id
得到 rooms.id
。
执行此操作的最佳方法是什么?
1.
SELECT r.id
FROM rooms r
WHERE '9af0521d-f999-42e8-aafd-4bf2d839eafb' in (user_id_one, user_id_two)
AND '0ff77b22-62f9-44ce-8f2e-7e85726dbb3e' in (user_id_one, user_id_two)
SELECT r.id
FROM rooms r
WHERE user_id_one in ('9af0521d-f999-42e8-aafd-4bf2d839eafb', '0ff77b22-62f9-44ce-8f2e-7e85726dbb3e')
AND user_id_two in ('9af0521d-f999-42e8-aafd-4bf2d839eafb', '0ff77b22-62f9-44ce-8f2e-7e85726dbb3e')
SELECT r.id
FROM rooms r
WHERE (
(user_id_one = '9af0521d-f999-42e8-aafd-4bf2d839eafb'
AND user_id_two = '0ff77b22-62f9-44ce-8f2e-7e85726dbb3e')
OR
(user_id_one = '0ff77b22-62f9-44ce-8f2e-7e85726dbb3e'
AND user_id_two = '9af0521d-f999-42e8-aafd-4bf2d839eafb')
)
或者完全不同的东西?
假设这两个用户 ID 永远不会有相同的值,那么您的所有三个版本都是有效的。我可以建议另一个版本,也许比您已有的版本更简洁:
SELECT id
FROM rooms r
WHERE LEAST(user_id_one, user_id_two) = '0ff77b22-62f9-44ce-8f2e-7e85726dbb3e' AND
GREATEST(user_id_one, user_id_two) = '9af0521d-f999-42e8-aafd-4bf2d839eafb';
上面least/greatest的做法是一箭双雕。无论匹配的 ID 集以何种顺序出现,上述方法都有效,因为它断言较小的 UUID 显示为一个用户 ID,较大的 UUID 显示为另一个用户 ID。
您可以通过数组进行比较:
WHERE ARRAY [user_id_one,user_id_two] @> ARRAY ['9af0521d-f999-42e8-aafd-4bf2d839eafb','0ff77b22-62f9-44ce-8f2e-7e85726dbb3e']
这里是 dbfiddle 示例
我会更改您的第二个查询,以便您只传递一次您想要的一对 uuid:
SELECT id
FROM rooms
WHERE (?, ?) IN ((user_id_one, user_id_two), (user_id_two, user_id_one));