使用连接或子查询选择单个列

时间:2015-03-21 09:05:41

标签: sql postgresql join subquery

我正在编写一个具有聊天功能并使用Postgres作为数据库的应用程序。涉及4个表 - 用户(保存用户数据,包括其ID),组(保存组列表,包括groupid),group_users(保存groupid到userid的映射,1到多个)和groupchats(保存映射) groupid到进入聊天的用户ID和文本本身)。所有表都有明显的外键。

我想获取属于给定groupid的groupchats中的所有行。但是,如果请求它的人在该组中,我只希望这样做。我还希望获得每一行的人的名字(请记住该行存储用户ID)。

以下是我的想法。我很好奇的是,如果有更好的方法吗?我正在使用子查询来获取当前行中用户的名称。我应该使用加入吗?另外,我相信我的第二个子查询(对于exists子句)应该只运行一次,我是否正确?或者我会在客户端逻辑中做得更好(对数据库进行第二次往返)?我想exxt DB可以优化这个。

SELECT userid, chat, time, 
      (SELECT firstname FROM users WHERE id=groupchat.userid) 
FROM groupchat 
WHERE groupid=$1 
  AND EXISTS (SELECT userid 
              from group_users 
              WHERE groupid=$1 AND userid=$2) 
ORDER BY time ASC;

1 个答案:

答案 0 :(得分:2)

你的方法很好。您可以将其写为明确的JOIN。使用关联还意味着您只需在查询中包含$1一次:

SELECT gc.userid, gc.chat, gc.time, u.firstname
FROM groupchat gc JOIN
     users u
     ON u.id = gc.userid
WHERE gc.groupid = $1 AND
      EXISTS (SELECT 1 
              FROM group_users fu
              WHERE gu.groupid = gc.groupid AND gu.userid = $2
             ) 
ORDER BY gc.time ASC;

如果您有大量数据,那么您需要以下索引:groupchat(groupid, time)users(id, firstname)group_users(groupid, userid)