简体   繁体   English

MySQL仅在子表中的记录与另一个子表中的记录匹配时才从父表中选择行

[英]MySQL select rows from parent table only if records in child table match records in another child table

I have two sets of parent/child tables: 我有两组父/子表:

  1. referrals / modalities_match_referrals 推荐/模态_match_referrals
  2. locations / modalities_match_providers 位置/方式_比赛_提供者

There is another table modalities which is a list of all of the modalities that we typically deal with. 还有另一个表格模式,它是我们通常处理的所有模式的列表。

For any referral, I need to find a list of providers (locations table) which can perform each of the modalities required by the referral. 对于任何引荐,我需要找到可以执行引荐所需的每种方式的提供程序列表(位置表)。 For example, if the referral requires an MRI and an arthrogram, the list of should be limited to those who can perform both an MRI and an arthrogram, even if such a provider offers other modalities besides the ones needed for this referral. 例如,如果转诊需要MRI和关节造影,则清单应仅限于既可以进行MRI也可以进行关节造影的人员,即使此类提供者提供了除此转诊所需的其他方式之外。

My question: is there a single query (with subqueries) that will result in a list of only those locations/providers who can perform all of the modalities linked to a referral through the modalities_match_referrals table? 我的问题:是否有一个查询(包含子查询),将仅列出可以执行通过modalities_match_referrals表链接到引荐的所有方式的那些位置/提供者的列表?

My problem is one of over-inclusion when a referral requires more than one modality. 我的问题是,当引荐需要不止一种方式时,过度包容性之一。 My query is resulting in a list of providers than can perform at least one of the modalities and is including providers that are not able to perform all modalities. 我的查询产生的提供商列表比可以执行至少一种模式的提供商还包括不能执行所有模式的提供商。

Here are the child/matching tables: 这是子/匹配表:

CREATE TABLE modalities_match_referrals (
id INT AUTO_INCREMENT PRIMARY KEY NOT NULL
,referral_id INT NOT NULL
,modality_id INT NOT NULL
,on_off TINYINT DEFAULT 0
,INDEX(referral_id)
,INDEX(modality_id)
,FOREIGN KEY(referral_id) REFERENCES referrals(id)
,FOREIGN KEY(modality_id) REFERENCES modalities(id)
);

CREATE TABLE modalities_match_providers (
id INT AUTO_INCREMENT PRIMARY KEY NOT NULL
,location_id INT NOT NULL
,modality_id INT NOT NULL
,on_off TINYINT DEFAULT 0
,INDEX(location_id)
,INDEX(modality_id)
,FOREIGN KEY(location_id) REFERENCES locations(id)
,FOREIGN KEY(modality_id) REFERENCES modalities(id)
);

What I have tried so far I have a long production query which is too long to include here, but I am getting the same list of providers from this shorter query and subqueries: 到目前为止,尝试过的工作有一个较长的生产查询,该查询太长了,无法包含在此处,但是从这个较短的查询和子查询中可以得到相同的提供程序列表:

SELECT locations.id AS 'Location ID'
,locations.name AS 'Provider'
FROM locations
JOIN (
    SELECT p.location_id
    FROM modalities_match_providers AS p
    RIGHT JOIN (
    SELECT modality_id
        FROM modalities_match_referrals
        WHERE on_off=1
        AND referral_id=9660        
    ) AS r ON r.modality_id = p.modality_id
    WHERE on_off=1
) AS l ON l.location_id=locations.id

WHERE locations.recycle=0
AND locations.locationstateid=1
GROUP BY locations.id
ORDER BY locations.name
LIMIT 10;

The results include providers that can perform MRIs and/or arthrograms, and what I am looking for are only those providers who can perform both. 结果包括可以执行MRI和/或关节造影检查的提供者,而我正在寻找的仅是可以同时执行这两种检查的提供者。

In the past, the modalities where handled as columns in both the referrals and locations tables. 过去,模式在引用表和位置表中均作为列处理。 The sql was a lot simpler but the issue with that system was having columns to those tables when a new modality was introduced (this happens more than you might think - open MRI vs stand up MRI, etc.) sql更加简单,但是当引入新模式时,该系统的问题是在这些表中包含列(这种情况比您想象的要多-开放MRI与站立MRI等)。

I'm also thinking of creating a PHP class to be called during the while loop that renders the list onto the webpage. 我还考虑创建一个在while循环期间调用的PHP类,以将列表呈现到网页上。 The class would do the comparing between modalities_match_referrals and modalities_match_providers and return true or false. 该类将在modalities_match_referrals和modalities_match_providers之间进行比较,并返回true或false。 Based on the return value, the provider would be displayed or not displayed. 根据返回值,将显示或不显示提供程序。 The downside there is complexity and I would be concerned about the performance of the page. 缺点是复杂,我会担心页面的性能。

Thank you in advance for any help you can offer. 预先感谢您提供的任何帮助。

Cross join the referral modalities with the locations so as to get the optimal result. 将推荐模式与位置交叉连接,以获得最佳结果。 Then outer join the providers' modalities to see how much is actually covered. 然后外部加入提供者的模式以查看实际涵盖了多少。 Use GROUP BY and HAVING the get the referral / location pairs that lack no modality. 使用GROUP BYHAVING获取没有模态的引用/位置对。

select
  r.referral_id,
  l.id as location_id
from modalities_match_referrals r
cross join locations l
left outer join modalities_match_providers p
  on  p.referral_id = r.referral_id
  and p.modality_id = r.modality_id
  and p.location_id = l.id
group by r.referral_id, l.id
having count(*) = count(p.id)
order by r.referral_id, l.id;

This should give you all referrals with all providers that can perform all their modalities. 这应该为您推荐所有可以执行其所有方式的提供程序。

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

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