0

我真的希望你能帮我解决这个问题。这是我当前的代码,到目前为止,它是我能做的最好的代码。

 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'
4

1 回答 1

3

匹配时通常lower()不需要,LIKE因为它默认不区分大小写

此外,当在字符串中间执行搜索时(例如LIKE '%whatever%),不使用索引。顺便问一下,你有任何索引吗?您是否尝试过构建查询计划?

正如我所看到的,这个问题几乎没有可能的解决方案:

  1. 使用全文搜索
  2. 添加另一个索引字段并在查询之前填充一次:

    update tblpms set tr13_flag=1 where CaseNo like '%tr13-011%'

    然后将每个where lower(CaseNo) like '%tr13-011%'语句替换为where tr13_flag=1

  3. 上述变化:使用索引PERSISTED 计算列,因此您避免手动计算标志。

  4. 一次将所有有价值的行抓取到临时表中:

    select * into #tr13011 from tblpms where lower(CaseNo) like '%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)
)
于 2013-03-27T07:18:39.793 回答