Not able to adress field in nested query - sql

I have such a query:
select d.r_object_id,
(select max(max_date) from (
SELECT max(sys_s.r_modify_date) AS max_date
FROM kc_mission_s mis_s, dm_sysobject_s sys_s
WHERE mis_s.r_object_id = sys_s.r_object_id AND mis_s.ka_document = d.r_object_id
union all
SELECT sys_s.r_modify_date AS max_date
FROM dm_document_s doc_s left join dm_sysobject_s sys_s on doc_s.r_object_id = sys_s.r_object_id
WHERE doc_s.r_object_id = d.r_object_id
)) as maxx
from kc_document_s d
The field d.r_object_id is not visible from the last nested query.
It will be visible if in-between query will be removed like this:
select d.r_object_id,
(
SELECT max(sys_s.r_modify_date) AS max_date
FROM kc_mission_s mis_s, dm_sysobject_s sys_s
WHERE mis_s.r_object_id = sys_s.r_object_id AND mis_s.ka_document = d.r_object_id
union all
SELECT sys_s.r_modify_date AS max_date
FROM dm_document_s doc_s left join dm_sysobject_s sys_s on doc_s.r_object_id = sys_s.r_object_id
WHERE doc_s.r_object_id = d.r_object_id
) as maxx
from kc_document_s d
But in this case I'm not allowed to select multiple rows.
What should I do?

If you continue the join from the middle level query into the lowest level query, and also include the join column at each level, then it should work
select d.r_object_id,
(select max(max_date) from (
SELECT max(sys_s.r_modify_date) AS max_date,
d.r_object_id
FROM kc_mission_s mis_s, dm_sysobject_s sys_s
WHERE mis_s.r_object_id = sys_s.r_object_id AND mis_s.ka_document = d.r_object_id
union all
SELECT sys_s.r_modify_date AS max_date,
d.r_object_id
FROM dm_document_s doc_s left join dm_sysobject_s sys_s on doc_s.r_object_id = sys_s.r_object_id
WHERE doc_s.r_object_id = d.r_object_id
) sub_query
where sub_query.r_object_id = d.r_object_id
) as maxx
from kc_document_s d

try this
select d.r_object_id,
greatest((select max(sys_s.r_modify_date) as max_date
from kc_mission_s mis_s, dm_sysobject_s sys_s
where mis_s.r_object_id = sys_s.r_object_id
and mis_s.ka_document = d.r_object_id),
(select sys_s.r_modify_date as max_date
from dm_document_s doc_s
left join dm_sysobject_s sys_s
on doc_s.r_object_id = sys_s.r_object_id
where doc_s.r_object_id = d.r_object_id)
) as maxx
from kc_document_s d

Related

Why is Oracle REPLACE function not working for this string?

We have a pattern we use all the time and this is usually pretty straightforward.
sortOrder IN VARCHAR2 := 'Title'
query VARCHAR2(32767) := q'[
SELECT
Columns
FROM tables
ORDER BY {sortOrder}
]';
query := REPLACE(query, '{sortOrder}', sortOrder);
But for this string it is not working:
WITH appl_List
AS
(
SELECT DISTINCT
appls.admin_phs_ORG_code || TO_CHAR(appls.serial_num, 'FM000000') AS core_proj_number,
appls.Appl_ID
FROM TABLE(:portfolioTable) appls
),
g1SupportingProjCount AS
(
SELECT
gen1grants.silverchair_id,
COUNT(DISTINCT al.Appl_ID) AS ApplCount
FROM
appl_List al
JOIN cg_cited_reference_gen1_grant gen1grants
ON al.core_proj_number = gen1grants.ic_serial_num
JOIN cg_cited_reference_gen1 gen1refs
ON gen1grants.silverchair_id = gen1refs.silverchair_id
GROUP BY gen1grants.Silverchair_id
),
g1SupportedPubCount AS
(
SELECT
gen1grants.silverchair_id,
COUNT(DISTINCT gen1refs.gen1_wos_uid) AS PubCount
FROM
appl_List al
JOIN cg_cited_reference_gen1_grant gen1grants
ON al.core_proj_number = gen1grants.ic_serial_num
JOIN cg_cited_reference_gen1 gen1refs
ON gen1grants.silverchair_id = gen1refs.silverchair_id
GROUP BY gen1grants.Silverchair_id
),
g2SupportingProjCount AS
(
SELECT
gen2grants.silverchair_id,
COUNT(DISTINCT al.Appl_ID) AS ApplCount
FROM
appl_List al
JOIN cg_cited_reference_gen2_grant gen2grants
ON al.core_proj_number = gen2grants.ic_serial_num
JOIN cg_cited_reference_gen2 gen2refs
ON gen2grants.silverchair_id = gen2refs.silverchair_id
GROUP BY gen2grants.Silverchair_id
),
g2SupportedPubCount AS
(
SELECT
gen2grants.silverchair_id,
COUNT(DISTINCT gen2refs.gen2_wos_uid) AS PubCount
FROM
appl_List al
JOIN cg_cited_reference_gen2_grant gen2grants
ON al.core_proj_number = gen2grants.ic_serial_num
JOIN cg_cited_reference_gen2 gen2refs
ON gen2grants.silverchair_id = gen2refs.silverchair_id
GROUP BY gen2grants.Silverchair_id
),
portfolio_cg_ids AS
(
SELECT DISTINCT md.silverchair_id
FROM
(
SELECT silverchair_id
FROM cg_cited_reference_gen1_grant gen1Grants
JOIN Appl_List appls
ON appls.core_proj_number = gen1Grants.ic_serial_num
UNION
SELECT silverchair_id
FROM cg_cited_reference_gen2_grant gen2Grants
JOIN Appl_List appls
ON appls.core_proj_number = gen2Grants.ic_serial_num
) grant_sc_ids
JOIN cg_metadata md
ON grant_sc_ids.silverchair_id = md.silverchair_id
)
SELECT
silverchairId,
TITLE,
PMID,
PMCID,
publication_year as year,
referenceCount1Gen,
supportingProjectCount1Gen,
supportedPublicationCount1Gen,
referenceCount2Gen,
supportingProjectCount2Gen,
supportedPublicationCount2Gen,
COUNT(1) OVER() as TotalCount
FROM
(
SELECT
md.SILVERCHAIR_ID silverchairId,
md.TITLE,
md.PMID,
md.PMCID ,
md.publication_year as year,
g1RefCounts.referenceCount1Gen as referenceCount1Gen,
g1SupportingProjCount.ApplCount as supportingProjectCount1Gen,
g1SupportedPubCount.PubCount as supportedPublicationCount1Gen,
g2RefCounts.referenceCount2Gen as referenceCount2Gen,
g2SupportingProjCount.ApplCount as supportingProjectCount2Gen,
g2SupportedPubCount.PubCount as supportedPublicationCount2Gen,
--COUNT(1) OVER() as TotalCount
FROM cg_metadata md
-- BEGIN datascope to current portfolio
JOIN portfolio_cg_ids
ON portfolio_cg_ids.silverchair_id = md.silverchair_id
-- END datascope to current portfolio
LEFT JOIN g1SupportingProjCount
ON g1SupportingProjCount.Silverchair_id = md.silverchair_id
LEFT JOIN g2SupportingProjCount
ON g2SupportingProjCount.Silverchair_id = md.silverchair_id
LEFT JOIN g1SupportedPubCount
ON g1SupportedPubCount.Silverchair_id = md.silverchair_id
LEFT JOIN g2SupportedPubCount
ON g2SupportedPubCount.Silverchair_id = md.silverchair_id
OUTER APPLY
(
Select Count(*) as referenceCount1Gen
FROM cg_cited_reference_gen1 g1Refs
WHERE g1Refs.silverchair_id = md.silverchair_id
) g1RefCounts
OUTER APPLY
(
Select Count(*) as referenceCount2Gen
FROM cg_cited_reference_gen2 g2Refs
WHERE g2Refs.silverchair_id = md.silverchair_id
) g2RefCounts
) results
ORDER BY {sortOrder}
Are there cases where some kind of special char in the string can keep this from working?
I'm kind of perplexed. I've been using this pattern for like 3 years and I've never had this not work.
What could be breaking this?
The query has 4000+ characters.
The text is probably being truncated somewhere down the line.

Convert Exist condition to Join with T-SQL

I am trying to convert the following T-SQL Select query to exclude "Exists" Clause and Include "Join" Clause. but i am ending up not getting the right result. can some one from this expert team help me with some tips.
select *
FROM HRData
INNER JOIN (
SELECT eeceeid, MIN(eecdateoftermination) eTermDate
FROM dbo.empcomp
INNER JOIN
(
SELECT xeeid FROM HRData_EEList
INNER JOIN dbo.empcomp t ON xeeid = eeceeid AND xcoid = eeccoid
WHERE eecemplstatus = 'T' AND eectermreason <> 'TRO' AND eeccoid <> 'WAON6'
AND EXISTS ( SELECT 1 FROM dbo.empded
INNER JOIN dbo.dedcode on deddedcode = eeddedcode AND deddedtype = 'MED' AND (eedbenstopdate IS NULL OR eedbenstopdate > '12/31/2005')
WHERE eedeeid = xeeid AND eedcoid = xcoid )
GROUP BY xeeid
HAVING COUNT(*) > 1) Term ON xeeid = eeceeid
group by eeceeid
) Terms ON eeid = eeceeid AND Termdate = eTermDate
The algorithm to convert EXISTS to JOIN is very simple.
Instead of
FROM A
WHERE EXISTS (SELECT *
FROM B
WHERE A.Foo = B.Foo)
Use
FROM A
INNER JOIN (SELECT DISTINCT Foo
FROM B) AS B
ON A.Foo = B.Foo
But the first one probably will be optimised better
Interesting request.
select *
FROM HRData
INNER JOIN (
SELECT eeceeid, MIN(eecdateoftermination) eTermDate
FROM dbo.empcomp
INNER JOIN
(
SELECT xeeid FROM HRData_EEList
INNER JOIN dbo.empcomp t ON xeeid = eeceeid AND xcoid = eeccoid
INNER JOIN
( SELECT DISTINCT xeeid, xcoid FROM dbo.empded
INNER JOIN dbo.dedcode on deddedcode = eeddedcode AND deddedtype = 'MED' AND (eedbenstopdate IS NULL OR eedbenstopdate > '12/31/2005')
-- WHERE eedeeid = xeeid AND eedcoid = xcoid
) AS A ON xeeid = A.xeeid AND eedcoid = A.eedcoid
WHERE eecemplstatus = 'T' AND eectermreason <> 'TRO' AND eeccoid <> 'WAON6'
GROUP BY xeeid
HAVING COUNT(*) > 1) Term ON xeeid = eeceeid
group by eeceeid
) Terms ON eeid = eeceeid AND Termdate = eTermDate
Another method of converting an exists to a join is to use a ROW_NUMBER() in the subselect to assist in removing duplicates.
EXISTS:
FROM A
WHERE EXISTS (SELECT *
FROM B
WHERE B.Condition = 'true' AND A.Foo = B.Foo)
JOIN:
FROM A
JOIN (SELECT B.Foo, ROW_NUMBER() OVER (PARTITION BY B.Foo ORDER BY B.Foo) RN
FROM B
WHERE B.Condition = 'true') DT
ON A.Foo = DT.Foo AND DT.RN = 1
The ORDER BY is totally arbitrary since you don't care which record it selects, but it's required. You may be able to use (SELECT NULL) instead.

Alternate way of Exists with Having clause

The below query is to retrieve the records whose (SGT_DISBURSEMENT_REQUEST) count is only one. It is working great. But performance wise it didn't took so much of time since we have 100 000 records.
Is there any better way to do it?
SELECT PA.PERSON_ID,
PA.PERSON_ACCOUNT_ID,
DR.DISBURSEMENT_REQUEST_ID,
SUM
(
ISNULL(CD.EE_PRE_TAX_AMT,0) +
ISNULL(CD.EE_ADDL_PRE_TAX_AMT,0)
) AS EE_PRE_TAX_CONTRIB,
DD.PRE_TAX_AMOUNT AS DISB_DTL_PRE_TAX_AMOUNT,
SUM
( ISNULL(CD.EE_POST_TAX_AMT,0) +
ISNULL(CD.EE_ADDL_POST_TAX_AMT,0)
) AS EE_POST_TAX_CONTRIB,
DD.POST_TAX_AMOUNT AS DISB_DTL_POST_TAX_AMOUNT
FROM SGT_DISBURSEMENT_REQUEST DR
INNER JOIN SGT_DISBURSEMENT_DETAIL DD ON DR.DISBURSEMENT_REQUEST_ID = DD.DISBURSEMENT_REQUEST_ID
INNER JOIN SGT_PERSON_ACCOUNT PA ON PA.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID
INNER JOIN SGT_CONTRIB_DTL CD ON CD.PERSON_ACCOUNT_ID = PA.PERSON_ACCOUNT_ID
WHERE DR.REQUEST_CATEGORY_VALUE = 'REFD' AND
DD.DETAIL_CATEGORY_VALUE = 'REFD' AND
CD.STATUS_VALUE = 'VALD' AND
CD.POSTED_DATE <= DR.ACCEPTED_TO_PAYROLL_DATE AND
DR.DISBURSEMENT_STATUS_VALUE <> 'CANL' AND
EXISTS
(
SELECT 1 FROM SGT_DISBURSEMENT_REQUEST SDR1
INNER JOIN SGT_DISBURSEMENT_DETAIL SDD1 ON SDD1.DISBURSEMENT_REQUEST_ID = SDR1.DISBURSEMENT_REQUEST_ID
WHERE SDR1.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID and SDD1.DETAIL_CATEGORY_VALUE = DD.DETAIL_CATEGORY_VALUE
GROUP BY SDR1.PERSON_ACCOUNT_ID
HAVING COUNT(*) = 1
)
GROUP BY
PA.PERSON_ID, PA.PERSON_ACCOUNT_ID, DR.DISBURSEMENT_REQUEST_ID, DD.PRE_TAX_AMOUNT, DD.POST_TAX_AMOUNT
For Performance improvement you can have the Filter Conditions in the Join Clause, instead of where clause. In this case each join will restrict the results to even lesser number of rows.
SELECT PA.PERSON_ID,
PA.PERSON_ACCOUNT_ID,
DR.DISBURSEMENT_REQUEST_ID,
SUM
(
ISNULL(CD.EE_PRE_TAX_AMT,0) +
ISNULL(CD.EE_ADDL_PRE_TAX_AMT,0)
) AS EE_PRE_TAX_CONTRIB,
DD.PRE_TAX_AMOUNT AS DISB_DTL_PRE_TAX_AMOUNT,
SUM
( ISNULL(CD.EE_POST_TAX_AMT,0) +
ISNULL(CD.EE_ADDL_POST_TAX_AMT,0)
) AS EE_POST_TAX_CONTRIB,
DD.POST_TAX_AMOUNT AS DISB_DTL_POST_TAX_AMOUNT
FROM SGT_DISBURSEMENT_REQUEST DR
INNER JOIN SGT_DISBURSEMENT_DETAIL DD ON DR.DISBURSEMENT_REQUEST_ID = DD.DISBURSEMENT_REQUEST_ID AND DR.REQUEST_CATEGORY_VALUE = 'REFD' AND
DD.DETAIL_CATEGORY_VALUE = 'REFD' AND DR.DISBURSEMENT_STATUS_VALUE <> 'CANL'
INNER JOIN SGT_PERSON_ACCOUNT PA ON PA.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID
INNER JOIN SGT_CONTRIB_DTL CD ON CD.PERSON_ACCOUNT_ID = PA.PERSON_ACCOUNT_ID AND CD.STATUS_VALUE = 'VALD' AND
CD.POSTED_DATE <= DR.ACCEPTED_TO_PAYROLL_DATE
WHERE EXISTS
(
SELECT 1 FROM SGT_DISBURSEMENT_REQUEST SDR1
INNER JOIN SGT_DISBURSEMENT_DETAIL SDD1 ON SDD1.DISBURSEMENT_REQUEST_ID = SDR1.DISBURSEMENT_REQUEST_ID
WHERE SDR1.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID and SDD1.DETAIL_CATEGORY_VALUE = DD.DETAIL_CATEGORY_VALUE
GROUP BY SDR1.PERSON_ACCOUNT_ID
HAVING COUNT(*) = 1
)
GROUP BY
PA.PERSON_ID, PA.PERSON_ACCOUNT_ID, DR.DISBURSEMENT_REQUEST_ID, DD.PRE_TAX_AMOUNT, DD.POST_TAX_AMOUNT
if you use count over it should give you the same result and be better for performance:
select * from (
SELECT PA.PERSON_ID,
PA.PERSON_ACCOUNT_ID,
DR.DISBURSEMENT_REQUEST_ID,
SUM
(
ISNULL(CD.EE_PRE_TAX_AMT,0) +
ISNULL(CD.EE_ADDL_PRE_TAX_AMT,0)
) AS EE_PRE_TAX_CONTRIB,
DD.PRE_TAX_AMOUNT AS DISB_DTL_PRE_TAX_AMOUNT,
SUM
( ISNULL(CD.EE_POST_TAX_AMT,0) +
ISNULL(CD.EE_ADDL_POST_TAX_AMT,0)
) AS EE_POST_TAX_CONTRIB,
DD.POST_TAX_AMOUNT AS DISB_DTL_POST_TAX_AMOUNT
,count(*) over(partition by PA.PERSON_ACCOUNT_ID ) as ct
FROM SGT_DISBURSEMENT_REQUEST DR
INNER JOIN SGT_DISBURSEMENT_DETAIL DD ON DR.DISBURSEMENT_REQUEST_ID = DD.DISBURSEMENT_REQUEST_ID
INNER JOIN SGT_PERSON_ACCOUNT PA ON PA.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID
INNER JOIN SGT_CONTRIB_DTL CD ON CD.PERSON_ACCOUNT_ID = PA.PERSON_ACCOUNT_ID
WHERE DR.REQUEST_CATEGORY_VALUE = 'REFD' AND
DD.DETAIL_CATEGORY_VALUE = 'REFD' AND
CD.STATUS_VALUE = 'VALD' AND
CD.POSTED_DATE <= DR.ACCEPTED_TO_PAYROLL_DATE AND
DR.DISBURSEMENT_STATUS_VALUE <> 'CANL'
GROUP BY
PA.PERSON_ID, PA.PERSON_ACCOUNT_ID, DR.DISBURSEMENT_REQUEST_ID, DD.PRE_TAX_AMOUNT, DD.PRE_TAX_AMOUNT, DD.POST_TAX_AMOUNT
) as x
where x.ct = 1
I would materialize this to a #temp
SELECT DR1.PERSON_ACCOUNT_ID, SDD1.DETAIL_CATEGORY_VALUE
FROM SGT_DISBURSEMENT_REQUEST SDR1
JOIN SGT_DISBURSEMENT_DETAIL SDD1
ON SDD1.DISBURSEMENT_REQUEST_ID = SDR1.DISBURSEMENT_REQUEST_ID
GROUP BY SDR1.PERSON_ACCOUNT_ID, SDD1.DETAIL_CATEGORY_VALUE
HAVING COUNT(*) = 1
join #temp
on #temp.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID
and #temp.DETAIL_CATEGORY_VALUE = DD.DETAIL_CATEGORY_VALUE

Left Join same table multiple times getting only the max value each join

I have the following query which returns multiple rows per join but I need to return only the row with the highest id
Any ideas how I can do this without sub-queries?
SELECT cp.RefId, work.PhoneNumber AS work, work.id AS work_id, home.PhoneNumber AS home, home.id AS home_id
FROM Contacts cp
LEFT JOIN OtherPhoneNumber work ON cp.ZoneId = work.ZoneId AND work.PhoneNumber_Type = 'W' AND work.OwnerType = 'C' AND work.OwnerRefId = cp.RefId
LEFT JOIN OtherPhoneNumber home ON cp.ZoneId = home.ZoneId AND home.PhoneNumber_Type = 'H' AND home.OwnerType = 'C' AND home.OwnerRefId = cp.RefId
WHERE cp.ZoneId = '123123'
This returns something like:
RefId work work_id home home_id
QWERTY1234 01234523423 1739092 01234563232 1818181
QWERTY1234 01234523423267196 1739093 01234563232 1818181
I only want:
RefId work work_id home home_id
QWERTY1234 01234523423267196 1739093 01234563232 1818181
One method is to extract the ids for the home and work numbers, and then join back to the original tables:
SELECT cp.RefId, work.PhoneNumber AS work, work.id AS work_id,
home.PhoneNumber AS home, home.id AS home_id
FROM Contacts cp LEFT JOIN
(SELECT o..OwnerRefId, o.zoneId,
MAX(CASE WHEN o..PhoneNumber_Type = 'W' THEN w.id END) as workid,
MAX(CASE WHEN o..PhoneNumber_Type = 'H' THEN w.id END) as homeid
FROM OtherPhoneNumber o
WHERE w.OwnerType = 'C'
GROUP BY o.OwnerRefId, o..zoneId
) wh
ON cp.RefId = w.OwnerRefId LEFT JOIN
OtherPhoneNumber work
ON work.id = wh.workid LEFT JOIN
OtherPhoneNumber home
ON home.id = wh.homeid
WHERE cp.ZoneId = '123123';
EDIT:
In SQL Server, you can do this using OUTER APPLY:
select cp.RefId, work.PhoneNumber AS work, work.id AS work_id,
home.PhoneNumber AS home, home.id AS home_id
from Contacts cp outer apply
(select top 1 o.*
from OtherPhoneNumber o
where o.PhoneNumber_Type = 'W' AND o.OwnerType = 'C' AND
o.OwnerRefId = cp.RefId AND o.ZoneId = cp.ZoneId
order by o.id desc
) work outer apply
(select top 1 o.*
from OtherPhoneNumber o
where o.PhoneNumber_Type = 'H' AND o.OwnerType = 'C' AND
o.OwnerRefId = cp.RefId AND o.ZoneId = cp.ZoneId
order by o.id desc
) home
where cp.ZoneId = '123123';
This is probably the fastest approach, with the right indexes: Contacts(ZoneId, RefId) and OtherPhoneNumber(ZoneId, OwnerRefId, PhoneNumber_Type, OwnerType, id).
Okay you can try this -
;WITH myCTE
AS
(
SELECT
cp.RefId
,work.PhoneNumber AS work
,work.id AS work_id
,home.PhoneNumber AS home
,home.id AS home_id
,ROW_NUMBER() OVER (PARTITION BY cp.RefId, work.PhoneNumber, work.id, home.PhoneNumber, home.id ORDER BY cp.RefId) AS RowNum
FROM Contacts cp
LEFT JOIN OtherPhoneNumber work
ON cp.ZoneId = work.ZoneId
AND work.PhoneNumber_Type = 'W'
AND work.OwnerType = 'C'
AND work.OwnerRefId = cp.RefId
LEFT JOIN OtherPhoneNumber home
ON cp.ZoneId = home.ZoneId
AND home.PhoneNumber_Type = 'H'
AND home.OwnerType = 'C'
AND home.OwnerRefId = cp.RefId
WHERE cp.ZoneId = '123123'
)
SELECT
*
FROM myCTE
WHERE RowNum = 1
You can use Outer Apply
SELECT cp.RefId, W.work, W.work_id, H.home, H.home_id
FROM Contacts cp
Outer Apply
(
Select Top 1 work.Id as work_id, work.PhoneNumber as work
From OtherPhoneNumber work
Where work.ZoneId = cp.ZoneId AND work.PhoneNumber_Type = 'W' AND work.OwnerType = 'C' AND work.OwnerRefId = cp.RefId
Order By Work.Id Desc
) W
Outer Apply
(
Select Top 1 home.Id as home_id, home.PhoneNumber as Home
From OtherPhoneNumber home
Where home.ZoneId = cp.ZoneId AND home.PhoneNumber_Type = 'H' AND home.OwnerType = 'C' AND home.OwnerRefId = cp.RefId
Order By H.Id Desc
) H
WHERE cp.ZoneId = '123123'

How do I group by the most recent date?

I have a HISTORY table that has multiple rows for the same record and I am trying to get the latest (closest to today's date) record. I am attempting to group by the closest date but am having a difficult time. Please check out the query below and advise me.
SELECT DISTINCT *
FROM
(SELECT etc.Complaint.Complaint_ID AS Complaint_ID
FROM etc.Complaint) AS Qry1
LEFT JOIN
(SELECT etc.Complaint.Complaint_ID AS Complaint_ID,
o.Action_User AS Resolved_User,
o.Action_Date AS LastActionDate
FROM etc.Complaint
LEFT OUTER JOIN etc.History as o
ON SUBSTRING(Primary_Key,15,LEN(Primary_Key) - 15) = etc.Complaint.Complaint_ID
AND TABLE_NAME = 'Resolution' AND o.Field_Name = 'Resolved_Ind'
AND New_Value = 1) AS Qry2
ON Qry1.Complaint_ID = Qry2.Complaint_ID
ORDER BY Qry1.Complaint_ID, MAX(Qry2.LastActionDate)
does this change help?
SELECT DISTINCT *
FROM
(SELECT etc.Complaint.Complaint_ID AS Complaint_ID FROM etc.Complaint) AS Qry1
LEFT JOIN
(SELECT etc.Complaint.Complaint_ID AS Complaint_ID,
o.Action_User AS Resolved_User,
o.Action_Date AS LastActionDate
FROM etc.Complaint
LEFT OUTER JOIN
(
SELECT SUBSTRING(Primary_Key,15,LEN(Primary_Key) - 15) as hist_Complaint_ID , MAX(Action_Date) as Action_Date
FROM etc.History
WHERE Field_Name = 'Resolved_Ind'
GROUP BY SUBSTRING(Primary_Key,15,LEN(Primary_Key) - 15)
) as o
ON o.hist_Complaint_ID = etc.Complaint.Complaint_ID
AND TABLE_NAME = 'Resolution' AND o.Field_Name = 'Resolved_Ind'
AND New_Value = 1) AS Qry2
ON Qry1.Complaint_ID = Qry2.Complaint_ID
ORDER BY Qry1.Complaint_ID, Qry2.LastActionDate
You can use ROW_NUMBER and a CTE to get it:
WITH cte AS (
SELECT etc.Complaint.Complaint_ID AS Complaint_ID,
o.Action_User AS Resolved_User,
o.Action_Date AS LastActionDate
row_number() over (partition by etc.Complaint.Complaint_ID order by o.Action_Date desc) AS rn
FROM etc.Complaint
LEFT OUTER JOIN etc.History as o
ON SUBSTRING(Primary_Key,15,LEN(Primary_Key) - 15) = etc.Complaint.Complaint_ID
AND TABLE_NAME = 'Resolution' AND o.Field_Name = 'Resolved_Ind'
AND New_Value = 1
)
SELECT * FROM cte
WHERE rn = 1