-4

查找访问过与其保险公司相关的所有骨科医生(专科)的患者。

数据库:单击此处查看 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;
4

3 回答 3

11

熟悉您拥有的数据:

第一个关键是了解您拥有哪些数据。在这种情况下,您有四个表

  • 保险公司
  • 病人
  • 医生
  • 访问

你的目标:

查找访问与其保险公司相关的所有骨科医师(专科)的所有患者的列表。

让我们退后一步,分小块分析它:

一般来说,从整体上看,这些要求可能会有点压倒性。让我们将需求拆分为更小的组件,以了解您需要做什么。

  1. A 部分:您需要找到专长为“骨科医师”的医生名单
  2. b 部分:查找在#1 中确定的就诊过医生的患者列表。
  3. c 部分:过滤结果 #2 以查找共享同一保险公司的患者和医生的列表。
  4. d 部分:找出与患者属于同一保险公司的骨科医生中的每一位的患者。

如何接近:

  1. 您需要确定您的主要目标,在本例中是确定患者列表。因此,首先查询 Patient 表。

  2. 你有病人,实际上是所有人,但我们需要找出这些病人中的哪些人去看了医生。让我们不要担心医生是否是骨科医生。我们只需要病人名单和他们去过的医生。Patient 和 Doctors 表之间没有映射。要了解这些信息,

    在正确的关键字段上加入 Patient 表和 Visits 表。

    然后在正确的关键字段上将输出与 Doctors 表连接起来。

  3. 如果您正确地完成了连接,您现在应该拥有他们访问过的所有患者和医生的列表。如果您使用LEFT OUTER JOIN,您甚至会发现从未看过医生的患者。如果您使用RIGHT OUTER JOIN,您将只找到看过医生的患者。

  4. 现在,您拥有他们访问过的所有患者和医生。但是,要求是只找到骨科医生。因此,应用条件过滤结果以仅给出所需的结果。

  5. 您现在已经实现了将要求拆分为部分 a部分 b中的较小组件。您仍然需要由保险公司对其进行过滤。这是棘手的部分,要求并没有说您需要显示保险公司,因此我们不必使用表 InsuranceCompanies。你的下一个问题将'How am I going to filter the results?'。有效点。找出三个表中的任何一个PatientDoctorVisits包含保险公司信息。Patient并且Doctors有一个共同的领域。加入该公共字段以过滤结果。

  6. 查找每位患者访问过的唯一骨科医生的数量。

  7. 这是可以通过多种方式完成的部分,其中一种方法是添加一个子查询,该查询将成为输出中的第四列。此子查询将查询表 Doctors 并按专业 = 'Orthopedist' 过滤。除了该过滤器之外,您还必须通过将内部表上的保险公司与主查询上的患者表上的保险公司 ID 进行匹配来进行过滤。此子查询将返回与患者数据匹配的保险公司 ID 的所有骨科医师的计数。

  8. 您现在应该拥有来自子查询的字段patient idpatient name和。然后,您可以添加一个外部连接,该连接将过滤来自此派生表的结果,其中包含与 匹配 的字段。我并不是说这是最好的方法。这是我能想到的一种方法。patients visits counttotal number of Orthopedists in same insurance companypatients visits counttotal number of Orthopedists in same insurance company

  9. 如果你按照上面的逻辑,你应该有这个。

看过所有医生的患者名单

仅由骨科医生筛选

由共享相同保险公司信息的患者和医生过滤。

同样,整个输出然后由派生表输出中的两个计数字段过滤。

球在你的球场上:

  • 一步一步尝试,一旦你找到答案。将其作为单独的答案发布在这里。我会赞成它以弥补你在这个问题上得到的所有反对票。

我相信你可以轻松做到这一点。

如果你绊倒...

不要犹豫,将您的问题发布为comments to this answer,其他人和我将很乐意为您提供帮助。

免责声明

我提供了如何实现此逻辑的多种方法之一。我确信有很多方法可以以更好的方式实现这一点。

结果:

请参阅@Ofek Ron 的答案以获取产生所需输出的正确查询。我没有写查询的任何部分。这都是OP的努力。

于 2012-05-05T15:27:38.393 回答
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

应用其余部分:单击此处查看 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);
于 2012-05-05T16:03:12.080 回答
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
于 2012-05-05T14:49:35.440 回答