聚合不在分组中的列

时间:2011-11-28 16:40:48

标签: sql sql-server-2008-r2

在T-SQL(SQL Server 2008 R2中,如果它是相关的),编写以下查询的最简洁方法是什么?

select dfd.ListName as ProvName, COUNT(distinct pv.PatientProfileId)
    from PatientVisit pv
        join DoctorFacility dfd on pv.DoctorId = dfd.DoctorFacilityId
    group by pv.DoctorId

我可以想到几种不同的方法。实际上,我可能只是通过dfd.ListName分组,但我只是偏执到担心雇用两个John Smiths。 :-)我知道另一种选择是

select dfd.ListName as ProvName, DistPatCount 
    from (
        select pv.DoctorId, COUNT(distinct pv.PatientProfileId) as DistPatCount
            from PatientVisit pv
            group by pv.DoctorId
        ) pvc 
        join DoctorFacility dfd on pvc.DoctorId = dfd.DoctorFacilityId

但“丑陋”是我能想到的最直接的方式来描述。 :-)此外,我认为有人会知道我错过的东西......

2 个答案:

答案 0 :(得分:2)

处理它的最简洁方法可能是创建患者数量的视图。我发现很难相信这是唯一有用的地方。

或者,您可以定义包含此信息的CTE(基本上是内联视图):

WITH Patient_Count (SELECT doctorId, COUNT(DISTINCT patientProfileId) as patientCount
                    FROM PatientVisit
                    GROUP BY doctorId)

SELECT a.listName as provName, b.patientCount
FROM DoctorFacility as a
JOIN Patient_Count as b
ON b.doctorId = a.doctorFacilityId

(虽然,doctorId真的等于doctorFacilityId吗?这似乎在说“是的,那位医生,他实际上是建筑”。)

答案 1 :(得分:1)

如果SQL更聪明一点,你可以做以下事情,因为你知道给定医生只能有一个设施。

select pv.DoctorId, dfd.ListName as ProvName, COUNT(distinct pv.PatientProfileId)
    from PatientVisit pv
        join DoctorFacility dfd on pv.DoctorId = dfd.DoctorFacilityId
    group by pv.DoctorId

不幸的是,SQL中的单值规则太严格了,它会阻止你这样做。单值规则是选择列表中的任何列必须在GROUP BY子句中或者在聚合函数中,而不管在类似情况下它实际上不是模糊的。上方。

因此,我们可以编写以下内容以符合SQL,即使逻辑上没有必要将ListName放在聚合函数中:

select pv.DoctorId, MAX(dfd.ListName) as ProvName, COUNT(distinct pv.PatientProfileId)
    from PatientVisit pv
        join DoctorFacility dfd on pv.DoctorId = dfd.DoctorFacilityId
    group by pv.DoctorId

我假设pv.DoctorId是一个引用dfd.DoctorFacilityId的外键,而不是相反。