我对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等...

我们如何使用混合表中包含的这个附加表来做同样的事情。

最佳答案

您需要两次连接表:

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

09-25 19:01