我真的希望你能帮我这个。这是我目前的代码,到目前为止,它是我能做的最好的代码。
SELECT
max(t2.pmskey) as pmskey, max(cast(t1.recdate as datetime)) as recdate,
max(t2.mrtype) as mrtype, max(cast(t1.mrdate as datetime)) as mrdate,
max(t2.CaseNo) as CaseNo, max(t2.pmclin) as pmclin,
max(cast(t1.nexteval as datetime)) as nexteval,
max(cast(t1.repdate as datetime)) as repdate,
max(t3.mrprocedure) as mrprocedure, max(t2.med_stat) as med_stat,
max(cast(t1.med_stateff as datetime)) as med_stateff,
max(t2.clincontact) as clincontact,
max(cast(t1.datemodf as datetime)) as datemodf, max(t2.modfby) as modfby,
max(cast(t1.inceptiondate as datetime)) as inceptiondate,
max(t2.createdby) as createdby, max(cast(t1.date_ent as datetime)) as date_ent,
max(t2.ppihandler) as ppihandler
FROM
tblpms as t1
JOIN
(
select * from tblpms where lower(CaseNo) like '%tr13-011%'
AND
cast(mrdate as datetime) IN (select max(cast(mrdate as datetime))
from tblpms where lower(CaseNo) like '%tr13-011%')
) as t2
on t1.CaseNo COLLATE DATABASE_DEFAULT = t2.CaseNo COLLATE DATABASE_DEFAULT
JOIN
(
select * from tblpms where lower(CaseNo) like '%tr13-011%'
AND
lower(mrprocedure) is not null and cast(nexteval as datetime)
in (select max(cast(nexteval as datetime)) from
tblpms where lower(CaseNo) like '%tr13-011%')
) as t3
on t1.CaseNo COLLATE DATABASE_DEFAULT = t2.CaseNo COLLATE DATABASE_DEFAULT
and lower(t2.CaseNo) like '%tr13-011%'
lower(CaseNo)
的条件在所有联接中被复制,我不知道如何减少这些条件。我相信有一些事情可以做。如果还有其他可以优化的内容,请将其包含在答案中。
这是我目前基于以下答案的查询。
SELECT
max(t2.pmskey) as pmskey, max(cast(t1.recdate as datetime)) as recdate,
max(t2.mrtype) as mrtype, max(cast(t1.mrdate as datetime)) as mrdate,
max(t2.CaseNo) as CaseNo, max(t2.pmclin) as pmclin,
max(cast(t1.nexteval as datetime)) as nexteval,
max(cast(t1.repdate as datetime)) as repdate,
max(t3.mrprocedure) as mrprocedure, max(t2.med_stat) as med_stat,
max(cast(t1.med_stateff as datetime)) as med_stateff,
max(t2.clincontact) as clincontact,
max(cast(t1.datemodf as datetime)) as datemodf, max(t2.modfby) as modfby,
max(cast(t1.inceptiondate as datetime)) as inceptiondate,
max(t2.createdby) as createdby, max(cast(t1.date_ent as datetime)) as date_ent,
max(t2.ppihandler) as ppihandler
FROM
tblpms as t1
JOIN
(
select * from tblpms where CaseNo = 'TR13-011-CRW'
AND
cast(mrdate as datetime) IN (select max(cast(mrdate as datetime))
from tblpms where CaseNo = 'TR13-011-CRW')
) as t2
on t1.CaseNo COLLATE DATABASE_DEFAULT = t2.CaseNo COLLATE DATABASE_DEFAULT
JOIN
(
select * from tblpms where CaseNo = 'TR13-011-CRW'
AND
lower(mrprocedure) is not null and cast(nexteval as datetime)
in (select max(cast(nexteval as datetime)) from
tblpms where CaseNo = 'TR13-011-CRW')
) as t3
on t1.CaseNo COLLATE DATABASE_DEFAULT = t2.CaseNo COLLATE DATABASE_DEFAULT
and CaseNo = 'TR13-011-CRW'
答案 0 :(得分:3)
与[{1}}匹配时,lower()
通常不需要LIKE
,因为它case-insensitive by default。
此外,当在字符串中间执行搜索(例如LIKE '%whatever%
)时,不使用索引。 顺便问一下,你有任何索引吗?您是否尝试过构建查询计划?
正如我所看到的,这个问题的解决方案很少:
添加另一个索引字段并在查询之前填充一次:
update tblpms set tr13_flag=1 where CaseNo like '%tr13-011%'
然后用where lower(CaseNo) like '%tr13-011%'
where tr13_flag=1
语句
上述方差:使用索引PERSISTED computed column,因此您可以避免手动计算标记。
将所有有价值的行抓到临时表中一次:
选择* 进入#tr13011 来自tblpms,其中较低(CaseNo)喜欢'%tr13-011%'
并加入它,可能在有趣的字段上添加索引。
此外,您cast
持续:cast(nexteval as datetime)
。使用答案中的第4个版本并同时转换为#temp
表。
这种情况对我来说毫无用处:and lower(mrprocedure) is not null and cast(nexteval as datetime)
。为什么不简单and mrprocedure is not null
?
版本4的示例
select
CaseNo,
mrprocedure,
cast(mrdate as datetime) as mrdate,
cast(nexteval as datetime) as nexteval
-- other required fields from tblpms table
into #tr13
from tblpms where CaseNo = 'TR13-011-CRW'
declare @max_mrdate datetime
declare @max_nexteval datetime
select @max_mrdate=max(mrdate), @max_nexteval=max(nexteval) from #tr13
SELECT
max(t2.pmskey) as pmskey, max(cast(t1.recdate as datetime)) as recdate,
max(t2.mrtype) as mrtype, max(cast(t1.mrdate as datetime)) as mrdate,
max(t2.CaseNo) as CaseNo, max(t2.pmclin) as pmclin,
max(cast(t1.nexteval as datetime)) as nexteval,
max(cast(t1.repdate as datetime)) as repdate,
max(t3.mrprocedure) as mrprocedure, max(t2.med_stat) as med_stat,
max(cast(t1.med_stateff as datetime)) as med_stateff,
max(t2.clincontact) as clincontact,
max(cast(t1.datemodf as datetime)) as datemodf, max(t2.modfby) as modfby,
max(cast(t1.inceptiondate as datetime)) as inceptiondate,
max(t2.createdby) as createdby, max(cast(t1.date_ent as datetime)) as date_ent,
max(t2.ppihandler) as ppihandler
FROM
tblpms as t1
JOIN
(
select * from #tr13 where mrdate = @max_mrdate
) as t2
on t1.CaseNo COLLATE DATABASE_DEFAULT = t2.CaseNo COLLATE DATABASE_DEFAULT
JOIN
(
select * from #tr13
where mrprocedure is not null and nexteval = @max_nexteval
) as t3
on t1.CaseNo COLLATE DATABASE_DEFAULT = t2.CaseNo COLLATE DATABASE_DEFAULT
drop table #tr13
我不确定为什么你需要COLLATE DATABASE_DEFAULT
,因为它总是在同一张桌子上。
逻辑对我来说不是很清楚,但似乎产生相同的结果,同时更具可读性(并且可能表现更好):
select
CaseNo,
mrprocedure,
cast(mrdate as datetime) as mrdate,
cast(nexteval as datetime) as nexteval,
pmskey,
mrtype,
med_stat,
clincontact,
modfby,
createdby,
ppihandler
-- other required fields from tblpms table
into #tr13
from tblpms where CaseNo = 'TR13-011-CRW'
declare @max_mrdate datetime
declare @max_nexteval datetime
select @max_mrdate=max(mrdate), @max_nexteval=max(nexteval) from #tr13
SELECT
max(t2.pmskey) as pmskey, max(cast(t1.recdate as datetime)) as recdate,
max(t2.mrtype) as mrtype, max(cast(t1.mrdate as datetime)) as mrdate,
max(t2.CaseNo) as CaseNo, max(t2.pmclin) as pmclin,
max(cast(t1.nexteval as datetime)) as nexteval,
max(cast(t1.repdate as datetime)) as repdate,
max(t2.mrprocedure) as mrprocedure, max(t2.med_stat) as med_stat,
max(cast(t1.med_stateff as datetime)) as med_stateff,
max(t2.clincontact) as clincontact,
max(cast(t1.datemodf as datetime)) as datemodf, max(t2.modfby) as modfby,
max(cast(t1.inceptiondate as datetime)) as inceptiondate,
max(t2.createdby) as createdby, max(cast(t1.date_ent as datetime)) as date_ent,
max(t2.ppihandler) as ppihandler
FROM tblpms as t1
JOIN #tr13 t2 on t1.CaseNo = t2.CaseNo
where
t2.mrdate = @max_mrdate
and t2.mrprocedure is not null
and t2.nexteval = @max_nexteval
drop table #tr13
<强>更新强> 我们设法将其减少为以下代码:
declare @max_mrdate datetime
declare @max_nexteval datetime
select
@max_mrdate=max(cast(mrdate as datetime)),
@max_nexteval=max(cast(nexteval as datetime))
from tblpms
where CaseNo = 'TR13-011-CRW'
select *
from tblpms where CaseNo = 'TR13-011-CRW'
and (
cast(mrdate as datetime) = @max_mrdate
or
(mrprocedure is not null and cast(nexteval as datetime) = @max_nexteval)
)