繁体   English   中英

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

[英]Is it possible to convert this subquery into a join?

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

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上,联接可能更快,但是我问这个问题的真正原因是我似乎无法制定联接来替换子查询,并且我想知道是否有可能。

您可以使用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方法相同的结果,但是恕我直言, 是一种更原则性,较少临时性的方法。

使用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

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

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

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

这被称为半连接,并且如果需要,可以使用(带有其他SELECTJOINSELECT子句重写为a)仅从“外部”表中进行项目,b)仅返回DISTINCT行:

SELECT DISTINCT T1.* 
  FROM T1
       JOIN T2 USING (id);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM