我对MySQL相当陌生,在弄清楚这一点时遇到了一些麻烦。
我有两个名为doctors
和doctor_tags
的表doctors
的字段:doctor_id
,doctor_name
doctor_tags
的字段:id
,doctor_id
,tag_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_joins
:doctor_id
,tag_id
因此标记表的字段更改为doctors_tags
:tag_id
,tag_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