如何在多个表中查找不同的用户
How to find distinct users in multiple tables
我有一个名为 users 的 table,它包含用户 ID,还有一些 table,例如 cloud_storage_a
、cloud_storage_b
和 cloud_storage_c
。如果 cloud_storage_a
中存在用户,则表示他们已连接到云存储 a。一个用户也可以存在于多个云存储中。这是一个例子:
users
table:
user_id | address | name
-------------------------------
123 | 23 Oak Ave | Melissa
333 | 18 Robson Rd | Steve
421 | 95 Ottawa St | Helen
555 | 12 Highland | Amit
192 | 39 Anchor Rd | Oliver
cloud_storage_a
:
user_id
-------
421
333
cloud_storage_b
:
user_id
-------
555
cloud_storage_c
:
user_id
-------
192
555
等等
我想创建一个查询来获取所有连接到任何云存储的用户。因此,对于此示例,应返回用户 421, 333, 555, 192
。我猜这是某种连接,但我不确定是哪一种。
你很接近。您不想使用基于键将 table 彼此相邻合并的 JOIN,而是使用将 recordsets/tables 堆叠在彼此之上的 UNION。
SELECT user_id FROM cloud_storage_a
UNION
SELECT user_id FROM cloud_storage_b
UNION
SELECT user_id FROM cloud_storage_c
在此处使用关键字 UNION
将使您在所有三个 table 中获得不同的 user_id。如果您将其切换为 UNION ALL
,您将不再获得 Distinct,它在其他情况下具有优势(显然不是在这里)。
编辑添加:
如果你想引入用户地址,你可以使用这个东西作为子查询并加入你的用户 table:
SELECT
subunion.user_id
user.address
FROM
user
INNER JOIN
(
SELECT user_id FROM cloud_storage_a
UNION
SELECT user_id FROM cloud_storage_b
UNION
SELECT user_id FROM cloud_storage_c
) subunion ON
user.user_id = subunion.user_id
随着您添加更多 cloud_storage_N table,该联盟将需要增长。总而言之,这不是一个很棒的数据库设计。创建一个 cloud_storage
table 并有一个字段描述它是 a
、b
、c
、... ,N
那么您的 UNION 查询将只是 SELECT DISTINCT user_id FROM cloud_storage;
,您将永远不需要再次编辑它。
您需要以这种方式加入未知(?)数量的表cloud_storage_X
。
您最好将架构更改为以下内容:
存储空间:
user_id cloud
------- -----
421 a
333 a
555 b
192 c
555 c
那么查询就这么简单:
select distinct user_id
from storage;
select u.* from users u,
cloud_storage_a csa,
cloud_storage_b csb,
cloud_storage_c csc
where u.user_id = csa.user_id or u.user_id = csb.user_id or u.user_id = csc.user_id
您应该简化架构以处理此类查询。
要从您的 users
table 中为所有(不同的)符合条件的用户获取列:
SELECT * -- or whatever you need
FROM users u
WHERE EXISTS (SELECT 1 FROM cloud_storage_a WHERE user_id = u.user_id) OR
EXISTS (SELECT 1 FROM cloud_storage_b WHERE user_id = u.user_id) OR
EXISTS (SELECT 1 FROM cloud_storage_c WHERE user_id = u.user_id);
只得到所有 user_id
而没有别的, 看起来不错。您 可以 将此结果加入 users
以获得相同的效果:
SELECT u.* -- or whatever you need
FROM users u
JOIN (
SELECT user_id FROM cloud_storage_a
UNION
SELECT user_id FROM cloud_storage_b
UNION
SELECT user_id FROM cloud_storage_c
) c USING user_id);
但这可能更慢。
我有一个名为 users 的 table,它包含用户 ID,还有一些 table,例如 cloud_storage_a
、cloud_storage_b
和 cloud_storage_c
。如果 cloud_storage_a
中存在用户,则表示他们已连接到云存储 a。一个用户也可以存在于多个云存储中。这是一个例子:
users
table:
user_id | address | name
-------------------------------
123 | 23 Oak Ave | Melissa
333 | 18 Robson Rd | Steve
421 | 95 Ottawa St | Helen
555 | 12 Highland | Amit
192 | 39 Anchor Rd | Oliver
cloud_storage_a
:
user_id
-------
421
333
cloud_storage_b
:
user_id
-------
555
cloud_storage_c
:
user_id
-------
192
555
等等
我想创建一个查询来获取所有连接到任何云存储的用户。因此,对于此示例,应返回用户 421, 333, 555, 192
。我猜这是某种连接,但我不确定是哪一种。
你很接近。您不想使用基于键将 table 彼此相邻合并的 JOIN,而是使用将 recordsets/tables 堆叠在彼此之上的 UNION。
SELECT user_id FROM cloud_storage_a
UNION
SELECT user_id FROM cloud_storage_b
UNION
SELECT user_id FROM cloud_storage_c
在此处使用关键字 UNION
将使您在所有三个 table 中获得不同的 user_id。如果您将其切换为 UNION ALL
,您将不再获得 Distinct,它在其他情况下具有优势(显然不是在这里)。
编辑添加:
如果你想引入用户地址,你可以使用这个东西作为子查询并加入你的用户 table:
SELECT
subunion.user_id
user.address
FROM
user
INNER JOIN
(
SELECT user_id FROM cloud_storage_a
UNION
SELECT user_id FROM cloud_storage_b
UNION
SELECT user_id FROM cloud_storage_c
) subunion ON
user.user_id = subunion.user_id
随着您添加更多 cloud_storage_N table,该联盟将需要增长。总而言之,这不是一个很棒的数据库设计。创建一个 cloud_storage
table 并有一个字段描述它是 a
、b
、c
、... ,N
那么您的 UNION 查询将只是 SELECT DISTINCT user_id FROM cloud_storage;
,您将永远不需要再次编辑它。
您需要以这种方式加入未知(?)数量的表cloud_storage_X
。
您最好将架构更改为以下内容:
存储空间:
user_id cloud
------- -----
421 a
333 a
555 b
192 c
555 c
那么查询就这么简单:
select distinct user_id
from storage;
select u.* from users u,
cloud_storage_a csa,
cloud_storage_b csb,
cloud_storage_c csc
where u.user_id = csa.user_id or u.user_id = csb.user_id or u.user_id = csc.user_id
您应该简化架构以处理此类查询。
要从您的 users
table 中为所有(不同的)符合条件的用户获取列:
SELECT * -- or whatever you need
FROM users u
WHERE EXISTS (SELECT 1 FROM cloud_storage_a WHERE user_id = u.user_id) OR
EXISTS (SELECT 1 FROM cloud_storage_b WHERE user_id = u.user_id) OR
EXISTS (SELECT 1 FROM cloud_storage_c WHERE user_id = u.user_id);
只得到所有 user_id
而没有别的,users
以获得相同的效果:
SELECT u.* -- or whatever you need
FROM users u
JOIN (
SELECT user_id FROM cloud_storage_a
UNION
SELECT user_id FROM cloud_storage_b
UNION
SELECT user_id FROM cloud_storage_c
) c USING user_id);
但这可能更慢。