Below query has two sub-queries in select statement and those are getting executed for each row. This is very inefficient and is there any way to optimize this in SQL Server?
SELECT
*
FROM
(
SELECT
t.id,
t.status,
CASE
WHEN (SELECT TOP 1 tt.code from text_view tt where tt.act_id = t.id ORDER BY tt.created_dt DESC) IN ('A', 'B', 'C','D','E') THEN
(SELECT TOP 1 created_dt from text_view tt where tt.act_id = t.id ORDER BY tt.created_dt DESC)
ELSE
NULL
END as notedate,
(select top 1 created_dt from act_mail tm where tm.act_id = t.id order by created_dt ASC ) AS [mail_dt],
FROM activity t
WHERE t.status not in ('CLOSED', 'ACT', 'CANCELED')
) q
WHERE q.notedate is not null
3条答案
按热度按时间voj3qocg1#
We can try using a join approach here:
yjghlzjz2#
You can take advantage of
NOT EXISTS
to find the latest record from theTEXT_VIEW
table and then useLEFT JOIN
andGROUP BY
to get the minimum date fromACT_MAIL
table as follows:vpfxa7rd3#
You want to select activities the latest text view of which has a code A-E. Probably the simplest method to get the latest text view is a
CROSS APPLY
(aka lateral inner join).You also want to know the oldest mail date. This is just
MIN(created_dt)
. You could get this with anOUTER APPLY
(aka lateral left outer join), but as this is about a single column, you can just as well keep this in yourSELECT
clause.As for a well performing query, you may want these indexex: