我对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
等等......
我们怎么能用混合中包含的附加表做同样的事情。
答案 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;