SQL Group by with aggregation and Distinct

时间:2012-04-24 20:23:53

标签: sql group-by distinct

鉴于:

保险公司( cid ,姓名,电话,地址)

医生(,姓名,专业,地址,电话,年龄,cid)

患者( pid ,姓名,地址,电话,年龄,性别,cid)

访问次数( vid ,确实,pid,日期,说明)

其中

cid - Insurance Company code
did - doctor code
pid - patient code
vid - code of visit

和任务:每位医生返回20-25岁(不同)患者的数量:

是:

SELECT  V.did, COUNT ( V.pid ) 
FROM    (   SELECT  DISTINCT V1.did, V1.pid
            FROM    Visits V1,Patient P
            WHERE   P.pid=V1.pid and P.age >= 20 and  P.age <=25 ) AS V 
GROUP BY    V.did

相当于:

SELECT  V.did, COUNT (DISTINCT V.pid ) 
FROM    Visits V,Patient P
WHERE   P.pid=V.pid and P.age >= 20 and  P.age <=25
GROUP BY    V.did

他们都是这项任务的好方法吗?

5 个答案:

答案 0 :(得分:3)

您的第二个查询更适合该任务,应该更好地进行优化。此外,在每个查询中,您引用Visit.age。你不应该加入专利和参考patient.age?

此外,每个人都在计算医生的独特访问,这不需要明确的陈述,因为访问永远不会重复。相反,你应该计算不同的患者(p.id)。

答案 1 :(得分:1)

第二个例子对我来说很好看。当将其编译成计划时,RDBMS将根据许多算法确定如何最好地处理它。我没有看到需要添加您在第一个版本中引入的中间步骤。

如果您非常希望确保自己拥有最佳方法,请查看生成的计划并进行比较。并查看读取,CPU时间等。

如何做到这一点取决于您使用的特定RDBMS。

答案 2 :(得分:0)

第一个查询有效,但实际上并不常见。

第二个问题是要走的路,更清楚的是发生了什么。

答案 3 :(得分:0)

这是两个不同的查询,可能是

1)您正在计算患者和医生之间的不同访问量,这意味着如果患者两次看病,您将无法计算

2)您只是计算医生的访问次数,如果同一患者有多次访问,他们将被计算两次

因此,对于任务,1)是正确答案,但2)看起来更好

SELECT  V.did, COUNT ( V.id ) 
FROM    (   SELECT  DISTINCT V1.did, V1.pid
            FROM    Visits V1
            WHERE V1.age >= 20 and  V1.age <=25 ) AS V  
GROUP BY    V.did

可以更好地写成

SELECT  V.did, COUNT ( V.pid ) ### change here
FROM    Visits, ### your joins
            WHERE V1.age >= 20 and  V1.age <=25 
GROUP BY    V.did

答案 4 :(得分:0)

您必须使用左连接,因为它显示for each doctor并且您没有显示没有使用0访问的医生:

select d.did, count(distinct p.pid) from doctor d
left join visits v on d.did = v.did
join patients p on v.pid = p.pid
where p.age between 20 and 25
group by d.did