2017-07-10 95 views
0

我有两套父/子表:MySQL的选择行只有在子表中匹配记录的记录在另一个子表

  1. 推荐/ modalities_match_referrals
  2. 位置/ modalities_match_providers

还有另一种表格模式,它是我们通常处理的所有模式的列表。

对于任何推荐,我需要找到一个提供商列表(位置表),它可以执行推介所需的每种模式。例如,如果转诊需要MRI和arthrogram,则该列表应限于可执行MRI和arthrogram的列表,即使此类提供者除了此转诊所需的其他方式之外也提供其他方式。

我的问题:是有一个单一的查询(子查询),这将导致只有那些位置/供应商谁可以执行所有通过modalities_match_referrals表链接到转诊的方式的名单?

我的问题是过度包含当推介需要多种形式时。我的查询产生了一个供应商列表,而不是可以执行至少一种模式,并且包括不能执行所有模式的供应商。

这里是孩子/匹配表:

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) 
); 

我已经试过到目前为止 我还有很长的生产的查询是太长,包括在这里,但我得到的同一列表从这个较短查询供应商和子查询:

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; 

结果包括可以进行核磁共振成像和/或arthrograms提供商和我所期待的只是那些谁可以执行两个供应商。

过去,在引用和位置表中作为列处理的模式。 sql比简单得多,但是当系统引入新的模式时,该系统的问题是在列表中添加列(这种情况超出了你的想象 - 打开MRI对比MRI等)

我是也考虑创建一个PHP类,在while循环中将该列表呈现到网页上。该类将执行modalities_match_referrals和modalities_match_providers之间的比较,并返回true或false。根据返回值,提供者将被显示或不显示。缺点是复杂性,我会担心页面的性能。

非常感谢您提供的任何帮助。

+1

HAVING COUNT(*)= 2 – Strawberry

+0

谢谢。这简直令人尴尬。 – commodore64

回答

0

将引荐模式与位置交叉连接以获得最佳结果。然后外部加入提供商的模式,看看实际覆盖了多少。使用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; 

这应该给大家推荐与可以执行他们所有的方式都提供商。

+0

谢谢Thorsten! – commodore64

相关问题