使用连接从两个不同的表中获取结果

时间:2016-10-04 03:50:56

标签: sql postgresql

假设我有以下表格:

+-------------------------------------------+
| t_classroom                               |
+-------------------------------------------+
| PK | id                                   |
|    | admin_user_id                        |
|    | name                                 |
|    | students                             |
+-------------------------------------------+

+-------------------------------------------+
| t_shared                                  |
+-------------------------------------------+
|    | admin_user_id                        |
|    | classroom_id                         |
|    | expiry                               |
+-------------------------------------------+

我想写一个查询,它将拉出admin_user_id有权访问的所有教室。从本质上讲,当我在admin_user_id表格中t_classroom进行搜索时,以及当我在admin_user_id表格中t_shared搜索时,我想要教室行。我做了以下尝试:

  SELECT
    id,
    admin_user_id,
    name,
    students
  FROM
    t_classroom
  WHERE
    admin_user_id = 1
  UNION ALL
  SELECT
    c.id,
    c.admin_user_id,
    c.name,
    students
  FROM
    t_classroom c
    INNER JOIN t_shared s 
    ON c.id = s.classroom_id
  WHERE
    admin_user_id = 1

以上看起来是否正确?还有什么更有效/更清洁的吗?

2 个答案:

答案 0 :(得分:1)

根据您拥有的数据量,您只需使用IN子句查看另一个表就可以获得。

  SELECT
    c.id,
    c.admin_user_id,
    c.name,
    c.students
  FROM
    t_classroom c
  WHERE
     c.admin_user_id = 1 
  OR c.id IN ( select s.classroom_id from t_shared s where s.admin_user_id = 1 )

您的工会无法工作,因为您已离开加入t_shared表并仅检查教室管理员用户。

如果你加入共享房间,你也会得到重复的内容,并且也需要区分结果。

修改

由于行数较多,最好在第二个表上使用存在检查。

  SELECT
    c.id,
    c.admin_user_id,
    c.name,
    c.students
  FROM
    t_classroom c
  WHERE
     c.admin_user_id = 1 
  OR EXISTS ( select 1 from t_shared s where s.classroom_id = c.id AND s.admin_user_id = 1 )

答案 1 :(得分:0)

您的解决方案基本上没问题,我在查看您的查询时可以检测到的唯一两个问题是:

  • 您需要在最后一行中编写s.admin_user_id而不是admin_user_id以避免出现错误消息,因为两个表中都有一个该列的列。最佳做法是始终使用表名限定列名。

  • 如果您希望在同一教室的两个表都有UNION的情况下避免重复的结果行,则可能需要使用UNION ALL而不是admin_user_id = 1。< / p>