最大活动日期寻找代码优化

时间:2014-10-16 00:45:13

标签: sql sql-server tsql

我正在使用下面的查询来查找需要在sql server 2008中进行收集活动的帐户它工作正常但是一旦数据在其中,我在power pivot中做了很多工作。我希望在sql查询中执行此操作,以使其更有效地工作并限制输出文件的大小。

标准是帐户有余额(xrxTrnLgr.Balance> 0),最后一次活动超过45天前发生。

活动日期由Max(xrxPatNotes.NoteDate)AS'Max of NoteDate',Max(xrxTrnIcf.PostDate)AS'Max of IcfPostDate',Max(xrxPat.EntryDate)AS'Entry Date',Max(xrxPat)表示.Coverage)AS'Coverage',Max(xrxTrnPay.PostDate)AS'最后付款'

我正在寻找一种更高效的查询,该查询会将最后一个活动日期作为列返回,并且只返回那些超过45天且没有活动的帐户。请帮忙。

SELECT DB_NAME() AS DataBaseName, xrxTrnLgr.PatId
     , MAX(xrxTrnLgr.Balance) AS 'BALANCE'
     , Max(xrxPatNotes.NoteDate) AS 'Max of NoteDate'
     , Max(xrxTrnIcf.PostDate) AS 'Max of IcfPostDate'
     , Max(xrxPat.EntryDate) AS 'Entry Date'
     , Max(xrxPat.Coverage) AS 'Coverage'
     , Max(xrxPat.DctId) AS 'Doctor'
     , Max(xrxTrnPay.PostDate) AS 'Last Payment'
FROM xrxTrnLgr 
LEFT OUTER JOIN xrxPatNotes ON xrxTrnLgr.PatId = xrxPatNotes.PatId
LEFT OUTER JOIN xrxTrnIcf ON xrxTrnLgr.PatId = xrxTrnIcf.PatId
LEFT OUTER JOIN xrxPat ON xrxTrnLgr.PatId = xrxPat.PatId
LEFT OUTER JOIN xrxTrnPay ON xrxTrnLgr.PatId = xrxTrnPay.PatId
GROUP BY xrxTrnLgr.PatId, xrxTrnLgr.Balance
HAVING (xrxTrnLgr.Balance>0)

3 个答案:

答案 0 :(得分:0)

with Acts (PatId, ActiveDate) as
(
SELECT PatId, max(NoteDate )
  FROM xrxPatNotes 
 GROUP BY PatId
UNION 
SELECT PatId, max(PostDate)
  FROM xrxTrnIcf 
  GROUP BY PatId
-- continue to UNION other activity tables
),
     ActsMoreThan45Days as
(
SELECT PatId,max(ActiveDate) as ActiveDate
  FROM Acts
 GROUP BY PatId
HAVING DATEDIFF(d, max(ActiveDate), GETDATE()) >= 45
)
SELECT DB_NAME() AS DataBaseName, 
       xrxTrnLgr.PatId, 
       xrxTrnLgr.Balance, 
       A45.ActiveDate, 
       xrxPat.Coverage,
       xrxPat.DctId AS Doctor
  FROM xrxTrnLgr 
  LEFT OUTER JOIN ActsMoreThan45Days A45
    ON xrxTrnLgr.PatId = A45.PatId
  LEFT OUTER JOIN xrxPat 
    ON xrxTrnLgr.PatId = xrxPat.PatId
 WHERE xrxTrnLgr.Balance>0
  1. 不是按照xrxTrnLgr上的余额列进行分组,而是将最大活动日期加入表xrxTrnLgr,这样会快得多。

  2. 要聚合所有活动表并分别获取最大活动日期,然后比较所有这些最大活动日期,效率会很高。

答案 1 :(得分:0)

不幸的是,SQL Server没有GREATEST功能,所以你可以像这样做一个UDF:

CREATE FUNCTION dbo.Greatest(@date1 datetime, @date2 datetime) RETURNS datetime
AS
BEGIN
    IF @date1 > @date2
        RETURN @date1
    RETURN @date2
END

然后按照以下方式进行查询:

SELECT
    DB_NAME() AS DataBaseName,
    xrxTrnLgr.PatId,
    MAX(xrxTrnLgr.Balance) AS 'BALANCE',
    dbo.Greatest(MAX(xrxPatNotes.NoteDate), dbo.Greatest(Max(xrxTrnIcf.PostDate), dbo.Greatest(Max(xrxPat.EntryDate), Max(xrxTrnPay.PostDate)) as 'Last Activity',
    Max(xrxPat.Coverage) AS 'Coverage',
    Max(xrxPat.DctId) AS 'Doctor'
FROM  xrxTrnLgr LEFT OUTER JOIN xrxPatNotes ON xrxTrnLgr.PatId = xrxPatNotes.PatId
LEFT OUTER JOIN  xrxTrnIcf ON xrxTrnLgr.PatId = xrxTrnIcf.PatId
LEFT OUTER JOIN xrxPat ON xrxTrnLgr.PatId = xrxPat.PatId
LEFT OUTER JOIN xrxTrnPay ON xrxTrnLgr.PatId = xrxTrnPay.PatId
GROUP BY xrxTrnLgr.PatId, xrxTrnLgr.Balance
HAVING (xrxTrnLgr.Balance>0) AND 
    DATEDIFF(d, dbo.Greatest(MAX(xrxPatNotes.NoteDate), dbo.Greatest(Max(xrxTrnIcf.PostDate), dbo.Greatest(Max(xrxPat.EntryDate), Max(xrxTrnPay.PostDate)), GETDATE()) > 45

答案 2 :(得分:0)

SELECT DB_NAME() AS DataBaseName, xrxTrnLgr.PatId
     , MAX(xrxTrnLgr.Balance) AS 'BALANCE'
     , Max(xrxPatNotes.NoteDate) AS 'Max of NoteDate'
     , Max(xrxTrnIcf.PostDate) AS 'Max of IcfPostDate'
     , Max(xrxPat.EntryDate) AS 'Entry Date'
     , Max(xrxPat.Coverage) AS 'Coverage'
     , Max(xrxPat.DctId) AS 'Doctor'
     , Max(xrxTrnPay.PostDate) AS 'Last Payment'
FROM xrxTrnLgr 
LEFT OUTER JOIN xrxPatNotes ON xrxTrnLgr.PatId = xrxPatNotes.PatId
LEFT OUTER JOIN xrxTrnIcf   ON xrxTrnLgr.PatId = xrxTrnIcf.PatId
LEFT OUTER JOIN xrxPat      ON xrxTrnLgr.PatId = xrxPat.PatId 
LEFT OUTER JOIN xrxTrnPay   ON xrxTrnLgr.PatId = xrxTrnPay.PatId
where xrxTrnLgr.Balance > 0
GROUP BY xrxTrnLgr.PatId 
HAVING datediff(dd, MAX(xrxTrnLgr.Balance)   , getdate()) > 45
   and datediff(dd, Max(xrxPatNotes.NoteDate), getdate()) > 45
   ... 

您可能正在寻找或