在查询MySQL中进行多个连接

时间:2014-05-29 17:53:32

标签: php mysql sql

我对MySQL很新,我在解决这个问题时遇到了一些麻烦。

我有两个名为doctorsdoctor_tags

的表格

doctors的字段:doctor_iddoctor_name

doctor_tags的字段:iddoctor_idtag_name

现在针对特定的doctor_id,我需要找到相关的医生。如果医生具有相同的tag_name,则相关。一旦我找到这种关系,我需要让所有这些医生doctor_name回来。

我几乎完全失去了我已经走了这么远(我确定这是错的)

SELECT doctors.doctor_name, doctors.doctor_id FROM doctors INNER JOIN doctors_tags ON doctors.doctor_id = doctors_tags.doctor_id ...

我认为这个查询很没用,但我知道我们需要某种类型的连接。

对于那些善于提出某种查询的人,如果你能在这个过程中解释它的每个部分,我将非常感激。谢谢:)

编辑:第2部分

如果我们说我们引入另一个在doctor_id和tag_id之间具有N:N关系的表

表字段 doctor_tags_joinsdoctor_idtag_id

因此标记表的字段变为

doctors_tagstag_idtag_name等等......

我们怎么能用混合中包含的附加表做同样的事情。

3 个答案:

答案 0 :(得分:2)

您需要两次加入表格:

SELECT DISTINCT d1.doctor_id, d2.doctor_name
FROM doctors AS d1
-- Get first doctor's tags
JOIN doctor_tags AS dt1 ON d1.doctor_id = dt1.doctor_id
-- Get all the other doctor_tags rows with the same tags
JOIN doctor_tags AS dt2 ON dt1.tag_name = dt2.tag_name 
    -- Don't list doctors as related to themselves
    AND dt1.doctor_id != dt2.doctor_id
-- Get those doctors' names
JOIN doctors AS d2 ON dt2.doctor_id = d2.doctor_id
ORDER BY d1.doctor_id, d2.doctor_name

我使用DISTINCT因此,如果他们有多个共同的标签,我们就不会为同一位医生获取多行。

如果您只是查找与特定医生相关的医生,而不是所有医生,则查询将变为:

SELECT doctor_name
FROM doctor_tags AS dt1
JOIN doctor_tags AS dt2 ON dt1.tag_name = dt2.tag_name AND dt1.doctor_id != dt2.doctor_id
JOIN doctors AS d2 ON dt2.doctor_id = d2.doctor_id
WHERE dt1.doctor_id = :doctor_id

其中:doctor_id是给定医生的占位符。您不需要第一个doctor表格,因为您没有使用该表格中的任何信息。

如果您想在一行中获取所有相关医生姓名,请使用GROUP_CONCAT

SELECT d1.doctor_id, GROUP_CONCAT(DISTINCT d2.doctor_name) AS related_doctors
FROM doctors AS d1
JOIN doctor_tags AS dt1 ON d1.doctor_id = dt1.doctor_id
JOIN doctor_tags AS dt2 ON dt1.tag_name = dt2.tag_name AND dt1.doctor_id != dt2.doctor_id
JOIN doctors AS d2 ON dt2.doctor_id = d2.doctor_id
GROUP BY d1.doctor_id

对于第二个问题,查询是相同的,除了您使用doctor_tags_join而不是doctor_tags。由于您未在结果中显示标记名称,因此doctor_tags表格无关紧要。

SELECT DISTINCT d1.doctor_id, d2.doctor_name
FROM doctors AS d1
JOIN doctor_tags_join AS dt1 ON d1.doctor_id = dt1.doctor_id
JOIN doctor_tags_join AS dt2 ON dt1.tag_id = dt2.tag_id 
    AND dt1.doctor_id != dt2.doctor_id
JOIN doctors AS d2 ON dt2.doctor_id = d2.doctor_id
ORDER BY d1.doctor_id, d2.doctor_name

答案 1 :(得分:1)

SELECT DISTINCT r.doctor_id, r.doctor_name
FROM doctors d
    INNER JOIN doctor_tags dt_d
        ON d.doctor_id = dt_d.doctor_id
    INNER JOIN doctor_tags dt_r
        ON dt_d.tag_name = dt_r.tag_name
    INNER JOIN doctors r
        ON dt_r.doctor_id = r.doctor_id
WHERE d.doctor_id = 12345

答案 2 :(得分:1)

您可以使用子查询来实现此目的。子查询只是另一个查询中的查询。这是如何逐步构建的

首先,您需要指定的doctor_id具有的tag_name,对吗?那就是:

select tag_name from doctors_tags where doctor_id='(your doctor_id)'

让所有医生使用相同的tag_name

SELECT doctor_id 
FROM doctors_tags 
WHERE tag_name in(
 SELECT tag_name FROM doctors_tags 
 WHERE doctor_id='(your doctor_id)' 
)

和最终查询,获取名称将是:

select doctors.doctor_name, doctors.doctor_id 
from doctors, doctors_tags 
where doctors_tags.tag_name in(
  SELECT tag_name FROM doctors_tags 
  WHERE doctor_id='(your doctor_id)' 
)
and doctors.doctor_id = doctors_tags.doctor_id;

希望有所帮助

修改

包含您的doctor_tags_joins表后,事情看起来像这样

select doctors.doctor_name, doctors.doctor_id
from doctors, doctors_tags, doctors_tags_joins
where doctors_tags.tag_name in
(
    select tag_name 
    from doctors_tags, doctors_tags_joins
    where doctors_tags_joins.doctor_id=(your id)
    and doctors_tags.tag_id=doctors_tags_joins.tag_id
)
and doctor_tags_joins.tag_id=doctors_tags.tag_id
and doctors.doctor_id=doctors_tags.doctor_id;