2014-02-25 30 views
-1

我不得不采取类似的代码如下:你如何使用左连接而不是分组?

SELECT courseId, termId, firstName, lastName 
FROM (
    SELECT s.courseId, s.termId, t.teacherId 
    FROM Teaches t, Section s 
    WHERE s.id = t.sectionId 
    GROUP BY s.termId, s.courseId 
    HAVING COUNT(DISTINCT t.teacherId) = 1 
) Teach, Person p 
WHERE p.id = teacherId 
ORDER BY courseId, termId; 

,并与1子查询,通过的不群,并且仅使用连接没有聚合函数(内连接,左连接,等等)把它变成一个MySQL声明。我一直在努力几个小时,但我无法找到一种不按功能使用组的方法。任何有识之士将不胜感激。

+0

用一点咖啡,一切皆有可能。嗯,但诚实地尝试穿上纸。一些P&P - 纸和铅笔,可能会帮助 – Coffee

+0

什么是'sectionId',是'Teaches'上的一列还是'Section'上的一列? – bjhaid

+0

我将代码稍微改了一点以clairfy @bjhaid – user2256498

回答

3

我相信这会返回一个等价的结果集,只使用JOIN和只有一个子查询。 (我还没有测试过。)

我解决这个问题的一般方法是使用一个允许的子查询,并使用NOT EXISTS谓词来测试“匹配”行的存在性。

SELECT s.courseId 
     , s.termId 
     , p.firstName 
     , p.lastName 
    FROM Section s 
    JOIN Teaches t 
    ON t.sectionID = s.id 
    LEFT 
    JOIN Person p 
    ON p.id = t.teacherId 
    WHERE NOT EXISTS 
     (SELECT 1 
      FROM Section c 
      JOIN Teaches d 
       ON d.sectionId = c.id 
      WHERE c.courseId = s.courseId -- match (as equivalent to group by) 
      AND c.termId  = s.termID  -- match (as equivalent to group by) 
      AND c.id  <> s.id   -- but not the same row (count=1) 
      AND d.teacherId <> t.teacherId -- but not the same row (count=1) 
     ) 
    ORDER 
    BY s.courseId 
     , s.termId 

在不相关子查询EXISTS谓词正在寻找一个匹配行,但当然,该行本身将匹配,所以我们需要将它排除在外。

我可能没有理解哪些列在哪些表中,所以我可能无法工作。 (限定查询中的所有列引用都是1)对读者的帮助,可能不知道哪些列位于哪个表中,以及2)避免查询被“不明确的列”异常无意中“破坏”,何时将相同名称的列添加到查询中涉及的其中一个表中。

我已经对Section中的id列的唯一性和Teaches中的teacherId列做了一些假设。

(的该部分并教结合使得它有点丑陋的事实,这将是更容易地看到,如果它是一个单一的表。)

SELECT t 
    FROM mytable t 
WHERE NOT EXISTS 
     (SELECT 1 
      FROM mytable d 
      WHERE d.somecol = t.somecol -- a match! 
      AND d.id  <> t.id  -- not the same row! 
     ) 

实际上,我认为这可能与抗来解决 - 连接模式,根本不使用任何子查询,但是连接在一起的三个表(Section,Teach和Person)使我很难围绕这一点来包装我的大脑。

+0

这有助于一吨,谢谢 – user2256498

+0

我实际上并没有看到原来的子查询是如何工作的,因为选定的列的teacher_id不在列中。 – zinking