是否可以将此子查询转换为连接?

时间:2012-01-17 03:34:08

标签: mysql sql

如果可能,我想用连接替换子查询。

SELECT `fftenant_farmer`.`person_ptr_id`, `fftenant_surveyanswer`.`text_value`
FROM `fftenant_farmer`
INNER JOIN `fftenant_person` 
ON (`fftenant_farmer`.`person_ptr_id` = `fftenant_person`.`id`) 
LEFT OUTER JOIN `fftenant_surveyanswer` 
ON fftenant_surveyanswer.surveyquestion_id = 1
AND fftenant_surveyanswer.`surveyresult_id` IN (SELECT y.`surveyresult_id` FROM `fftenant_farmer_surveyresults` y WHERE y.farmer_id = `fftenant_farmer`.`person_ptr_id`)

我试过了:

SELECT `fftenant_farmer`.`person_ptr_id`, `fftenant_surveyanswer`.`text_value`#, T5.`text_value`
FROM `fftenant_farmer`
INNER JOIN `fftenant_person` 
ON (`fftenant_farmer`.`person_ptr_id` = `fftenant_person`.`id`) 
LEFT OUTER JOIN `fftenant_farmer_surveyresults` 
ON (`fftenant_farmer`.`person_ptr_id` = `fftenant_farmer_surveyresults`.`farmer_id`) 
LEFT OUTER JOIN `fftenant_surveyanswer` 
ON (`fftenant_farmer_surveyresults`.`surveyresult_id` = `fftenant_surveyanswer`.`surveyresult_id`) 
AND fftenant_surveyanswer.surveyquestion_id = 1 

但是,对于那个农民来说,这给每个农民每个调查结果一个记录。我只想要第一个查询返回的每个农民一条记录。

大多数RDBM上的连接可能会更快,但我问这个问题的真正原因是我似乎无法制定一个连接来替换子查询,我想知道它是否可能。

3 个答案:

答案 0 :(得分:3)

您可以使用DISTINCTGROUP BY,正如mvds和Brilliand所建议的那样,但我认为如果您将最后一个连接更改为内连接,但提升其优先级,则更接近查询的设计意图:

SELECT farmer.person_ptr_id, surveyanswer.text_value
  FROM fftenant_farmer AS farmer
 INNER
  JOIN fftenant_person AS person
    ON person.id = farmer.person_ptr_id
  LEFT
 OUTER
  JOIN
(      fftenant_farmer_surveyresults AS farmer_surveyresults
 INNER
  JOIN fftenant_surveyanswer AS surveyanswer
    ON surveyanswer.surveyresult_id = farmer_surveyresults.surveyresult_id
   AND surveyanswer.surveyquestion_id = 1
)
    ON farmer_surveyresults.farmer_id = farmer.person_ptr_id

从广义上讲,这最终会得到与DISTINCTGROUP BY方法相同的结果,但会采用更原则,更少 ad hoc 的方式,恕我直言。< / p>

答案 1 :(得分:2)

使用SELECT DISTINCT或GROUP BY删除重复的条目。

尽可能少地改变你的尝试:

SELECT DISTINCT `fftenant_farmer`.`person_ptr_id`, `fftenant_surveyanswer`.`text_value`#, T5.`text_value`
FROM `fftenant_farmer`
INNER JOIN `fftenant_person` 
ON (`fftenant_farmer`.`person_ptr_id` = `fftenant_person`.`id`) 
LEFT OUTER JOIN `fftenant_farmer_surveyresults` 
ON (`fftenant_farmer`.`person_ptr_id` = `fftenant_farmer_surveyresults`.`farmer_id`) 
LEFT OUTER JOIN `fftenant_surveyanswer` 
ON (`fftenant_farmer_surveyresults`.`surveyresult_id` = `fftenant_surveyanswer`.`surveyresult_id`) 
AND fftenant_surveyanswer.surveyquestion_id = 1

答案 2 :(得分:1)

  

我问这个问题的真正原因是我似乎无法制定一个联接来替换子查询,我想知道它是否可能

然后考虑一个更简单的例子,例如以

SELECT * 
  FROM T1
 WHERE id IN (SELECT id FROM T2);

这被称为semi join,如果需要,可以使用(除其他可能性之外)使用JOIN条款重新编写a)项目仅来自'外部' 'table,和b)只返回SELECT行:

DISTINCT