带条件的SQL表值的MAX或MIN

时间:2018-06-22 19:59:45

标签: sql performance optimization max min

您好,我希望有人可以告诉我一种更好的方法来执行此操作,但是我的方法很慢,并且导致我的查询运行了4秒钟以上。这些表都有索引,在执行计划中我看不到任何东西。

我想从我的表中获取最小的EvaluationId,其中initial = 1,以及最大的maximationId。

是否有更好的方法可以将表两次连接?

select
r.PatientId,
MAX(r.ReferralId),
MIN(a.AssessmentOneId),
MAX(a1.AssessmentOneId)
from dbo.Referral r
inner join dbo.Patient p on p.PatientId = r.PatientId
left join dbo.AssessmentOne a on a.ReferralId = r.ReferralId and a.Initial = 1
left join dbo.AssessmentOne a1 on a1.ReferralId = r.ReferralId
where
p.AccountId = @pAccountId
group by r.PatientId

我也使用子查询尝试了以下方法,但是性能仍然很差。

select
r.PatientId,
MAX(r.ReferralId),
(Select MIN(a.AssessmentOneId) from dbo.AssessmentOne a where a.ReferralId = MAX(r.ReferralId) and a.Initial = 1),
(Select MAX(a.AssessmentOneId) from dbo.AssessmentOne a where a.ReferralId = MAX(r.ReferralId))
from dbo.Referral r
inner join dbo.Patient p on p.PatientId = r.PatientId
where
p.AccountId = @pAccountId
group by r.PatientId

您能提供的任何帮助将不胜感激

2 个答案:

答案 0 :(得分:2)

对于此查询:

select r.PatientId, MAX(r.ReferralId), MIN(a.AssessmentOneId), 
       MAX(a1.AssessmentOneId)
from dbo.Referral r inner join
     dbo.Patient p
     on p.PatientId = r.PatientId left join
     dbo.AssessmentOne a
     on a.ReferralId = r.ReferralId left join
     dbo.AssessmentOne a1
     on a1.ReferralId = r.ReferralId
where p.AccountId = @pAccountId
group by r.PatientId;

我建议在Patient(AccountId, PatientId)Referral(PatientId, ReferralId)AssessmentOne(ReferalId, Initial)上建立索引。

双重联接有点奇怪。因此,我将其写为:

select p.PatientId, max(r.ReferralId), max(a.AssessmentOneId), 
       max(case when a.Initial = 1 then a.AssessmentOneId end)
from dbo.Referral r inner join
     dbo.Patient p
     on p.PatientId = r.PatientId left join
     dbo.AssessmentOne a
     on a.ReferralId = r.ReferralId 
where p.AccountId = @pAccountId
group by p.PatientId;

我怀疑这确实会影响性能,但对我来说似乎更简单。

答案 1 :(得分:1)

推荐表是患者与评估之间m:n关系的桥梁表。由于您希望每位患者获得某些评估ID,因此有必要加入表格,这是您正在做的事情。但是,由于我们必须查看每个患者的所有评估以获取最大数量,因此我们可以即时获得最小的初始评估ID:

select
  p.patientid,
  max(r.referralid),
  min(case when initial = 1 then assessmentoneid end),
  max(assessmentoneid)
from dbo.patient p
join dbo.referral r on on r.patientid = p.patientid
left join dbo.assessmentone a on a.referralid = r.referralid
where p.accountid = @paccountid
group by p.patientid;

您将需要这些索引:

  • 患者(帐户,患者)
  • 引荐(患者编号,referralid)
  • 评估人(推荐人,评估人,初始)