2011-08-03 48 views
2

我靠近这一点拉我的头发。这是我正在处理的查询:这是一个MySQL错误还是我疯了?查询没有返回足够的结果

  SELECT 
      *, 
      GROUP_CONCAT(DISTINCT d.title SEPARATOR ', ') AS departments, 
      MAX(d.department_id) AS department_id, 
      CONCAT(friendly_last_name, ', ', friendly_first_name) AS professor_name, 
      IF(p.reviews = 0, "", p.quality) AS quality, 
      IF(p.reviews = 0, "", p.reviews) AS reviews, 
      IF(p.reviews = 0, "", p.ease) AS ease, 
      u.url 
     FROM 
      educational.professors_departments 
      LEFT JOIN educational.professors p USING (professor_id) 
      LEFT JOIN educational.departments d USING (department_id) 
      LEFT JOIN educational.universities u ON (p.university_id = u.university_id) 
     WHERE 
      p.university_id = 3231 
      AND d.department_id IN ('91') 
     GROUP BY 
      professor_id 
     ORDER BY p.friendly_last_name ASC, p.friendly_first_name ASC 

当我按原样运行该查询时,得到101个结果。如果我在查询的末尾添加一个简单的LIMIT 20,则突然查询返回一个结果。

好像这并不奇怪,如果我将LIMIT 20更改为LIMIT 25,我会收到25个结果。是否有一些神奇的东西,我错过了这个?我不能为我的生活弄清楚。

P.S. - 我试过SQL_NO_CACHE无济于事。 P.P.S. - 如果我删除整个ORDER BY子句,但保留LIMIT 20 ...我得到20个结果

+0

我使用SQLYog获得相同的结果,没有直接在shell中尝试,但SQLYog没有做任何有趣的事情处理和理论上应该完全一样。 –

+0

是否有可能实际获得前20个结果的空值,并且它们没有显示为shell中的文本,或者是否从shell中获得'x rows returned'消息? – dfb

+0

SQLYog说“1行返回”,但只是为了确保我将它运行在一个shell中,并获得了一行“集合中的一行” –

回答

2

我只能猜测引擎正在尽力猜测一些元素...您已经离开了连接不相信是你真正想要的......只是NORMAL加入...我首先试着对你的查询进行一次EXPLAIN,看看它出现了什么,可能会显示与索引,全表扫描等的洞察力...

此外,使用select *通常是不好的,懒惰的查询。获取你想要和期望的列。如果一个结构发生了变化,而你依靠*,那么你将来可能无法预见到结果。

我会重组如下,看到的结果并检查其EXPLAIN

SELECT STRAIGHT_JOIN 
     p.Professor_ID, 
     CONCAT(p.friendly_last_name, ', ', p.friendly_first_name) AS professor_name, 
     GROUP_CONCAT(DISTINCT d.title SEPARATOR ', ') AS departments, 
     MAX(d.department_id) AS department_id, 
     IF(p.reviews = 0, "", p.quality) AS quality, 
     IF(p.reviews = 0, "", p.reviews) AS reviews, 
     IF(p.reviews = 0, "", p.ease) AS ease, 
     u.url 
    FROM 
     educational.professors p 
     JOIN educational.professors_departments pd 
      on p.Professor_ID = pd.Professor_ID 
      JOIN educational.departments d 
       on pd.Department_ID = d.Department_ID 
       AND d.department_id IN ('91') 
     JOIN educational.universities u 
      ON p.university_id = u.university_id 
    WHERE 
     p.university_id = 3231 
    GROUP BY 
     p.professor_id 
    ORDER BY 
     p.friendly_last_name ASC, 
     p.friendly_first_name ASC 
    LIMIT 20 

看你的IF()子句质量,评价,缓解......是你故意只在P得到这些值仅。所有3个元素的评论= 0 ...或者他们应该代表每个值的列...

+0

使用正常连接尝试获得了相同的结果。 SELECT *在那里用于调试,我没有在开发中使用它(但是我确实很欣赏你对细节的关注)。您的查询似乎工作。是的,我打算使用p.reviews = 0,因为如果p.reviews = 0,p.quality和p.ease没有任何关联。试图找出你的查询是如何使它工作的。 –

+0

@Colin Morelli,无论如何,STRAIGHT_JOIN可以帮助解决复杂的查询结构。 – DRapp

+0

先生,您是一位天才......更不用说英雄了,因为您只是挽救了我的头发。毕竟是说完了,我的查询(不管相信与否)的问题是JOIN子句中USING与ON的区别(尝试了其他所有更改,这是唯一有所作为的部分)。但是,我使用了重组查询,因为它在我的基准测试中跑得更快。谢谢。 –

相关问题