避免使用内部连接的笛卡尔积

时间:2013-08-31 17:51:41

标签: sql syntax cartesian-product

我知道以前曾经问过这个问题,但是我很难理解它。我很少使用原始SQL 我有三个表格 - SessionGroupNameGroupSessionFeedback

我将Session加入GroupFeedback idUser 我正在GroupName列加入SessionidGroup

这是我的SQL代码:

SELECT s.idSession, 
       g.name, 
       s.Assistant, 
       s.idGroup, 
       s.start, 
       s.end, 
       f.value
  FROM rempad.Session s
 INNER JOIN rempad.GroupSessionFeedback f
    ON s.idUser = f.idUser
 INNER JOIN rempad.GroupName g
    ON s.idGroup = g.idGroup
 WHERE s.start BETWEEN '2013-04-28' AND '2013-05-28'
   AND s.idUser = 22
    OR s.idUser = 23
    OR s.idUser = 24
    OR s.idUser = 26
    OR s.idUser = 27
    OR s.idUser = 28
    OR s.idUser = 42;

我希望它能带回独特的idSessions,但由于联接而多次匹配它,我真的不知道采取什么其他方法。我可以单独调用数据库 - 但我真的试图避免锤击数据库,因为它的响应非常慢。

有什么想法吗?

提前致谢

3 个答案:

答案 0 :(得分:2)

我使用了此页面上的示例:SQL query returning cartesian product来弄明白。公平地说,我没有在我的问题中提供数据库结构。但问题是,在我加入的每个表中都有多个匹配的列,所以我需要在我的Join语句中反映出来。这是一个样本

 INNER JOIN rempad.GroupSessionFeedback f
 ON s.idUser = f.idUser 
 AND s.idSession = f.idSession 
 AND s.idGroup = f.idGroup

我希望这有助于其他人。 →

答案 1 :(得分:0)

尝试使用:

select {.......}
from session s inner join groupsessionfeedback f inner join groupname g
on s.iduser = f.iduser and s.idgroup = g.idgroup
where {.......}

我希望这能解决它。但是,如果此查询中需要任何其他过滤器,请告诉我。

答案 2 :(得分:0)

此版本的查询是否遇到同样的问题:

SELECT s.idSession, g.name, s.Assistant, s.idGroup, s.start, s.end, f.value
  FROM rempad.Session s
 INNER JOIN rempad.GroupSessionFeedback f
    ON s.idUser = f.idUser
 INNER JOIN rempad.GroupName g
    ON s.idGroup = g.idGroup
 WHERE s.start BETWEEN '2013-04-28' AND '2013-05-28'
   AND s.idUser in (22, 23, 24, 26, 27, 28, 42);

如果它仍然产生重复的结果,那么你想要的是什么行?毕竟,这将解决多个idsession的问题,但它不会返回g.namef.value

SELECT distinct s.idSession, s.Assistant, s.idGroup, s.start, s.end
  FROM rempad.Session s
 INNER JOIN rempad.GroupSessionFeedback f
    ON s.idUser = f.idUser
 INNER JOIN rempad.GroupName g
    ON s.idGroup = g.idGroup
 WHERE s.start BETWEEN '2013-04-28' AND '2013-05-28'
   AND s.idUser in (22, 23, 24, 26, 27, 28, 42);