0

我正在尝试创建一个报告以提供来自 SQL Server 数据库的数据。我有 3 张我感兴趣的表格,客户、推荐人、约会。客户可以有 1.* 推荐,推荐可以有 0.* 预约。

在我的报告中,我想显示从收到推荐到第一次约会的平均时间。

我在我的存储过程中尝试上述方法,但收到“无法对包含聚合或子查询的表达式执行聚合函数”。

有没有一种巧妙的方法可以在没有您能想到的子查询的情况下使其工作?

编辑下面的粗略表结构。

客户 ClientID INT IIDENTITY (pk) Forename VARCHAR(50) Surname VARCHAR(50) DOB DATETIME

Referral ReferralID INT IDENTITY (pk) ClientID INT (fk) ReferralRequestReceivedDate DATETIME OrgaisationAreaId INT (fk)

Appointment AppintmentID INT IDENTITY (pk) ReferralId INT(fk) AppointmentDate DATETIME AttendanceTypeId INT (fk) AppointmentTypeID INT (fk)

AttendanceTypes AttendanceTypeID INT IDENTITY (pk) 名称 VARCHAR(50)

AppointmentTypes AppointmentTypeID INT IDENTITY (pk) 名称 VARCHAR(50)

OrganisationArea OrgaisationAreaId INT IDENTITY(pk) 名称 VARCHAR(50)

我现有的 proc 有按年龄和出勤类型出席的约会计数,如下所示......

SELECT OA.Name, 
COUNT(CASE WHEN AppointmentTypeId IN(1,3) 
               AND AppointmentDate BETWEEN '27 Jan 2013' AND '13 Apr 2013' 
               THEN AppointmentId END) AS AppsBooked,
AVG(DATEDIFF(d, ReferralRequestReceivedDate, MIN(A.AppointmentDate))) 
AS AvgAllocationWaitTime

FROM OrganisationAreas OA
LEFT OUTER JOIN Clients C
    ON OA.OrganisationAreaId = C.OrganisationAreaId
LEFT OUTER JOIN IaptReferrals R 
    ON C.ClientId = R.ClientId
LEFT OUTER JOIN IaptAppointments A
    ON R.IaptReferralId = A.Referral_IaptReferralId

GROUP BY OA.OrganisationAreaId, OA.Name
4

2 回答 2

1

如果不使用子查询或 cte,我想不出办法。但如果你对子查询没问题,试试这个

SELECT OA.Name, 
COUNT(CASE WHEN 
            AppointmentTypeId IN(1,3) AND AppointmentDate BETWEEN '27 Jan 2013' AND '13 Apr 2013' THEN AppointmentId 
      END) AS AppsBooked,
AVG(DATEDIFF(d, ReferralRequestReceivedDate, sq.MinAppointmentDate)) AS AvgAllocationWaitTime
FROM OrganisationAreas OA
LEFT OUTER JOIN
(
    SELECT  C.OrganisationAreaId, MIN(A.AppointmentDate) MinAppointmentDate 
    FROM IaptAppointments A
    LEFT OUTER JOIN IaptReferrals R ON R.IaptReferralId = A.Referral_IaptReferralId
    LEFT OUTER JOIN Clients C ON C.ClientId = R.ClientId 
    GROUP BY C.OrganisationAreaId
) sq ON sq.OrganisationAreaId = OA.OrganisationAreaId
GROUP BY OA.OrganisationAreaId, OA.Name

或 cte 版本:

;WITH cte AS 
(
    SELECT C.OrganisationAreaId, MIN(A.AppointmentDate) MinAppointmentDate 
    FROM IaptAppointments A
    LEFT OUTER JOIN IaptReferrals R ON R.IaptReferralId = A.Referral_IaptReferralId
    LEFT OUTER JOIN Clients C ON C.ClientId = R.ClientId
    GROUP BY C.OrganisationAreaId
)
SELECT OA.Name, 
COUNT(CASE WHEN 
            AppointmentTypeId IN(1,3) AND AppointmentDate BETWEEN '27 Jan 2013' AND '13 Apr 2013' THEN AppointmentId 
      END) AS AppsBooked,
AVG(DATEDIFF(d, ReferralRequestReceivedDate, cte.MinAppointmentDate)) AS AvgAllocationWaitTime
FROM OrganisationAreas OA
LEFT OUTER JOIN cte ON cte.OrganisationAreaId = OA.OrganisationAreaId
GROUP BY OA.OrganisationAreaId, OA.Name
于 2013-04-23T05:43:43.507 回答
0

你有这个:

SELECT OA.Name, 
COUNT(CASE WHEN AppointmentTypeId IN(1,3) 
               AND AppointmentDate BETWEEN '27 Jan 2013' AND '13 Apr 2013' 
               THEN AppointmentId END) AS AppsBooked,
AVG(DATEDIFF(d, ReferralRequestReceivedDate, MIN(A.AppointmentDate))) 
AS AvgAllocationWaitTime

FROM OrganisationAreas OA
LEFT OUTER JOIN Clients C
    ON OA.OrganisationAreaId = C.OrganisationAreaId
LEFT OUTER JOIN IaptReferrals R 
    ON C.ClientId = R.ClientId
LEFT OUTER JOIN IaptAppointments A
    ON R.IaptReferralId = A.Referral_IaptReferralId

GROUP BY OA.OrganisationAreaId, OA.Name

让我们看看如何改进它。首先,如果您想要推荐日期和第一次约会之间的平均时间,您需要内部联接,而不是外部联接。其次,您有一个没有 else 条件的 case 构造。第三,您对已预订的约会有所了解,这似乎无关紧要。最后,您收到错误语法的错误消息。

要修复最后一个错误,请将最小约会日期移至子查询。这将使您的查询如下所示:

select oa.name
, avg(datediff(d, ReferralRequestReceivedDate, MinAppointmentDate)) 
AvgAllocationWaitTime

from OrganisationAreas oa 
JOIN Clients C
    ON OA.OrganisationAreaId = C.OrganisationAreaId
JOIN IaptReferrals R 
    ON C.ClientId = R.ClientId
join (
select referral_iaptReferralId refid
, min(appointmentdate) MinAppointmentDate
from IaptAppointments
where clause goes here
group by referral_iaptReferralId
) temp on refid = r.iaptReferralId

where clause goes here

保持这个基本结构。如果您还想要约会计数,请尽量保持简单。

于 2013-04-22T22:58:16.950 回答