我正在尝试创建一个报告来提供来自SQL Server数据库的数据。我有3个我感兴趣的桌子,客户,推荐,预约。客户可以拥有1. *推荐,推荐人可以预约0. *约会。
在我的报告中,我想显示从收到推荐到第一次约会的平均时间。
我在我的存储过程中尝试了上述操作,但收到“无法对包含聚合或子查询的表达式执行聚合函数。”
如果没有您能想到的子查询,是否有一种灵活的方法可以让它工作?
编辑下面的粗糙表结构。
客户端 ClientID INT IIDENTITY(pk) Forename VARCHAR(50) 姓氏VARCHAR(50) DOB DATETIME
推荐 ReferralID INT IDENTITY(pk) ClientID INT(fk) ReferralRequestReceivedDate DATETIME OrgaisationAreaId INT(fk)
预约 AppintmentID INT IDENTITY(pk) ReferralId INT(fk) 约会日期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)
我现有的处理程序有按照年龄和出勤类型参加的预约计数如下...
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
答案 0 :(得分: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
答案 1 :(得分: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
保持这个基本结构。如果您还想要约会,请尽量保持简单。