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

时间:2015-10-20 19:08:13

标签: sql postgresql join distinct exists

我有一个名为users的表,其中包含用户ID,以及一些表,如cloud_storage_acloud_storage_bcloud_storage_c。如果cloud_storage_a中存在用户,则表示他们已连接到云存储a。用户也可以存在于许多云存储中。这是一个例子:

users表:

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。我猜这是某种加入,但我不确定是哪一种。

4 个答案:

答案 0 :(得分:4)

你很亲密。您需要使用UNION将记录集/表堆叠在一起,而不是基于键将表紧密合并的JOIN。

SELECT user_id FROM cloud_storage_a
UNION
SELECT user_id FROM cloud_storage_b
UNION
SELECT user_id FROM cloud_storage_c

在此处使用关键字UNION将为您提供跨所有三个表的不同user_id。如果您将其切换为UNION ALL,您将不再获得“区别”,这在其他情况下具有优势(显然不在此处)。

编辑添加:

如果您想引入用户地址,可以将此内容用作子查询并加入您的用户表:

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表时,该联盟将需要增长。总而言之,它并不是一个出色的数据库设计。您最好创建一个cloud_storage表,并使用一个字段来描述哪一个abc,...,{{1 }}

然后您的UNION查询将只是N,您将永远不需要再次编辑它。

答案 1 :(得分:1)

您需要以这种方式加入未知(?)数量的表cloud_storage_X

您最好将架构更改为以下内容:

存储

user_id cloud
------- -----
 421     a
 333     a
 555     b
 192     c
 555     c

然后查询就像这样简单:

select distinct user_id
from   storage;

答案 2 :(得分:1)

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

您应该简化架构以处理此类查询。

答案 3 :(得分:0)

users表中获取所有(不同)合格用户的列:

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而没有别的,@JNevill's UNION query看起来不错。您可以将此结果加入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);

但那可能比较慢。