2016-10-04 115 views
0

比方说,我有如下表:获取结果

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

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

我想写一个查询,将拉动所有的教室,一个admin_user_id访问。实质上,当我在表中搜索admin_user_id时,我想要教室行的联合以及当我在表中搜索admin_user_id时教室行。我做了以下尝试:

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 

以上看起来是否正确?有没有更高效/更清洁的东西?

+0

会请您提供一些示例数据和结果? – Esty

回答

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表,仅检查教室管理员用户。

如果你加入共享房间,你最终也会得到重复的结果,并且需要将结果分开。

编辑:

由于大量的行可能会更好使用一个存在于第2表检查的。

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) 
+0

只是为了给大小的指示,两个表都将在100几百万行中 –

0

你的解决办法是从根本上很好,唯一的两个问题,我可以目测查询时发现是:

  • 你需要写s.admin_user_id,而不是admin_user_id在最后一行,以避免错误信息,因为这两个表中都有该名称的列。最佳做法是总是用表名限定列名。

  • 你可能想使用UNION而不是UNION ALL如果你想避免的情况下重复的结果行,这两个表具有admin_user_id = 1对于同一个教室。