我正在使用下面的查询来查找需要在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)
答案 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
不是按照xrxTrnLgr上的余额列进行分组,而是将最大活动日期加入表xrxTrnLgr,这样会快得多。
要聚合所有活动表并分别获取最大活动日期,然后比较所有这些最大活动日期,效率会很高。
答案 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
...
您可能正在寻找或