如何在多个表中查找不同的用户

How to find distinct users in multiple tables

我有一个名为 users 的 table,它包含用户 ID,还有一些 table,例如 cloud_storage_acloud_storage_bcloud_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 并有一个字段描述它是 abc、... ,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);

但这可能更慢。