查找访问过与保险公司相关的所有骨科医生(专科)的患者。
数据库:Click here to view the sample data script in SQL Fiddle.
CREATE VIEW Orthos AS
SELECT d.cid,d.did
FROM Doctors d
WHERE d.speciality='Orthopedist';
CREATE VIEW OrthosPerInc AS
SELECT o.cid, COUNT(o.did) as countd4i
FROM Orthos o
GROUP BY o.cid;
CREATE VIEW OrthoVisitsPerPat AS
SELECT v.pid,COUNT(o.did) as countv4d
FROM Orthos o,Visits v,Doctors d
WHERE o.did=v.did and d.did=o.did
GROUP BY v.pid,d.cid;
SELECT p.pname,p.pid,p.cid
FROM OrthoVisitsPerPat v, OrthosPerInc i,Patient p
WHERE i.countd4i = v.countv4d and p.pid=v.pid and p.cid=i.cid;
DROP VIEW IF EXISTS Orthos,OrthosPerInc,OrthoVisitsPerPat;
如何在一个查询中编写它?
到目前为止,我试图解决这个问题。
SELECT p.pid,p.pname,p.cid,COUNT(v.did)
FROM Visits v
JOIN Doctors d ON v.did=d.did
JOIN Patient p ON p.pid=v.pid
WHERE d.cid=p.cid and d.speciality="Orthopedist"
GROUP BY p.pid,p.cid;
INTERSECT
SELECT p.pid,d.cid,COUNT(d.did)
FROM Doctors d
JOIN Patient p ON p.cid=d.cid
WHERE d.speciality='Orthopedist'
GROUP BY d.cid;
答案 0 :(得分:11)
第一个关键是了解您拥有的数据。在这种情况下,您有四个表
查看所有访问过与保险公司相关的所有骨科医生(专科)的患者名单。
一般来说,当你整体看它们时,要求可能有点压倒性。让我们将需求分成更小的组件,以了解您需要做什么。
您需要确定您的主要目标,在这种情况下,以确定患者列表。因此,首先查询Patient表。
你有患者,实际上所有患者,但我们需要找到哪些患者去看医生。让我们不要担心医生是否是骨科医生。我们只需要患者名单和他们访问过的医生。患者和医生表之间没有映射。要了解这些信息,
使用正确的关键字段的Visits表加入Patient表。
然后将输出与Doctors表连接到正确的关键字段。
如果您已正确完成加入,您现在应该拥有所有患者和他们访问过的医生的清单。如果您使用LEFT OUTER JOIN
,您甚至会发现从未去过医生的患者。如果您使用RIGHT OUTER JOIN
,您将只找到去看医生的患者。
现在,您有所有患者和他们访问过的医生。但是,要求只找到骨科医生的医生。因此,应用条件来过滤结果,只给出所需的结果。
您现在已经在 part a 和 part b 中拆分为更小的组件。您仍然需要由保险公司过滤它。这是一个棘手的部分,要求并不是说你需要展示保险公司,所以我们不必使用保险公司表。您的下一个问题是'How am I going to filter the results?'
。有效点。找出三个表Patient
,Doctor
和Visits
中的任何一个是否包含保险公司信息。 Patient
和Doctors
有一个共同的字段。加入该公共字段以过滤结果。
查找每位患者访问过的唯一骨科医生的计数。
以下是可以通过多种方式完成的部分,其中一种方法是添加一个子查询,该查询将是输出中的第四列。该子查询将查询表医生并按特殊情况过滤='骨科医生'。除了该过滤器之外,您还必须通过将内部表上的保险公司与主查询上的患者表上的保险公司ID进行匹配来进行过滤。该子查询将返回与患者数据匹配的保险公司ID的所有骨科医生的计数。
您现在应该拥有来自子查询的字段patient id
,patient name
,patients visits count
和total number of Orthopedists in same insurance company
。然后,您可以添加外部联接,该联接将在patients visits count
与total number of Orthopedists in same insurance company
匹配的字段中过滤此派生表的结果。我不是说这是最好的方法。这是我能想到的一种方法。
如果你遵循上面的逻辑,你应该有这个。
访问过所有医生的病人名单
仅由医生进行过滤,他们是骨科医生
由患者和医生过滤共享相同的保险公司信息。
然后,整个输出将被派生表输出中的两个计数字段过滤。
我相信你可以轻松地做到这一点。
不要犹豫,将您的问题发布为comments to this answer
,其他人和我将很乐意为您提供帮助。
我已经提供了如何实现这种逻辑的众多方法之一。我确信有很多方法可以更好地实现这一点。
请参阅@Ofek Ron的答案,以获得产生所需输出的正确查询。我没有写任何查询部分。这是OP的全部努力。
答案 1 :(得分:4)
@Siva的解释:
这是第1-5部分的结果代码:
SELECT *
FROM Patient p
JOIN Visits v ON v.pid=p.pid
JOIN Doctors d ON d.did=v.did and d.cid=p.cid
WHERE d.speciality="Orthopedist"
应用第6部分:
SELECT p.pid,COUNT(d.did)
FROM Patient p
JOIN Visits v ON v.pid=p.pid
JOIN Doctors d ON d.did=v.did and d.cid=p.cid
WHERE d.speciality="Orthopedist"
GROUP BY p.pid
应用其余部分:Click here to view the demo in SQL Fiddle.
SELECT p.pid,p.cid,COUNT(DISTINCT d.did) as c
FROM Patient p
JOIN Visits v ON v.pid=p.pid
JOIN Doctors d ON d.did=v.did and d.cid=p.cid
WHERE d.speciality="Orthopedist"
GROUP BY p.pid
HAVING (p.cid,c) IN
(SELECT d.cid,COUNT(DISTINCT d.did)
FROM Doctors d
WHERE d.speciality="Orthopedist"
GROUP BY d.cid);
答案 2 :(得分:0)
也许是这样的:
SELECT
p.pname,
p.pid,
p.cid
FROM
Patient AS p
JOIN
(
SELECT v.pid,COUNT(o.did) as countv4d
FROM Doctors d
JOIN Visits v ON o.did=v.did
WHERE d.speciality='Orthopedist'
GROUP BY v.pid,d.cid;
) AS v
ON p.pid=v.pid
JOIN
(
SELECT o.cid, COUNT(o.did) as countd4i
FROM Doctors d
WHERE d.speciality='Orthopedist'
GROUP BY o.cid;
) AS i
ON p.cid=i.cid
WHERE
i.countd4i = v.countv4d