Reputation: 97
I've been trying to figure this one out for a while but nothing seems to work for me and maybe a bit of assistance will help me understand it better. I'm joining multiple tables but only want the max date associated with an ID number. There could be multiple dates associated with an ID number. If I take out the MAX(Date) piece, it will run but return multiple date values. I don't want the MAX(Date) to be in the initial select but only within the WHERE clause. Here's my query:
SELECT DISTINCT A.ID , C.Date
FROM IDTable A
INNER JOIN AccountTable B
ON B.AccountID = A.AccountID
FULL OUTER JOIN Updates U
ON U.ID = A.ID
FULL OUTER JOIN Update2 C
ON C.AccountID = B.AccountID
INNER JOIN UserTable UT
ON UT.UserMnemonicID = A.AssignedTo
WHERE A.StatusID NOT IN ('Complete','Open')
--Need help here to only return MAX date value:
AND C.Date=(SELECT MAX(C.Date) FROM Update2)
ORDER BY A.ID
Upvotes: 5
Views: 105939
Reputation: 40309
Here's my take. With complex queries, there are always multiple solutions...
First, get the latest date for every AccountID
select AccountID, max(Date)
from Update2
group by AccountID
Stick this in a subquery, join back to the table to only get the "latest" entry
select CInner.*, CMax.MaxDate
from Update2 CInner
inner join (-- Max date for every AccountID
select AccountID, max(Date) MaxDate
from Update2
group by AccountID) CMax
on CMax.AccountID = CInner.AccountID
and CMax.MaxDate = CInner.Date
Plug this back into the original query. Made it all a subquery to keep the Full Outer Join distinct (I also moved the inner joins together for comprehensibility)
SELECT DISTINCT A.ID , C.Date
FROM IDTable A
INNER JOIN AccountTable B
ON B.AccountID = A.AccountID
INNER JOIN UserTable UT
ON UT.UserMnemonicID = A.AssignedTo
FULL OUTER JOIN Updates U
ON U.ID = A.ID
FULL OUTER JOIN (-- Update2, with latest date
select CInner.*, CMax.MaxDate
from Update2 CInner
inner join (-- Max date for every AccountID
select AccountID, max(Date) MaxDate
from Update2
group by AccountID) CMax
on CMax.AccountID = CInner.AccountID
and CMax.MaxDate = CInner.Date) C
ON C.AccountID = B.AccountID
WHERE A.StatusID NOT IN ('Complete','Open')
--Need help here to only return MAX date value:
AND C.Date=(SELECT MAX(C.Date) FROM Update2)
ORDER BY A.ID
This is as far as I can go. The problem here is that all JOINs will be resolved before the WHERE clause, so in the current form all those FULL OUTER JOINs are kind of pointless, as only those resulting rows with the max(Date) will be included.
To mention, I find queries with full outer joins very difficult to get right. The fact that you have two in your query makes my eyes water, and moreso as they "branch off" of your core inner join queries. Are you definite that they need to be there?
Upvotes: 1
Reputation: 1653
If you don't want the MAX(date) in the initial Select then this would work:
SELECT DISTINCT A.ID , C.Date
FROM IDTable A
INNER JOIN AccountTable B
ON B.AccountID = A.AccountID
FULL OUTER JOIN Updates U
ON U.ID = A.ID
FULL OUTER JOIN Update2 C
ON C.AccountID = B.AccountID
INNER JOIN UserTable UT
ON UT.UserMnemonicID = A.AssignedTo
WHERE A.StatusID NOT IN ('Complete','Open')
AND C.Date=
(SELECT MAX(C2.Date)
FROM Update2 C2
WHERE C2.AccountID = C.AccountID)
ORDER BY A.ID
Upvotes: 10
Reputation: 28890
In SQL Server ,use ROWNUMBER..
;with cte
as
(
SELECT A.ID , C.Date,row_number() over (partition by a.id order by c.date desc) as rn
FROM IDTable A
INNER JOIN AccountTable B
ON B.AccountID = A.AccountID
FULL OUTER JOIN Updates U
ON U.ID = A.ID
FULL OUTER JOIN Update2 C
ON C.AccountID = B.AccountID
INNER JOIN UserTable UT
ON UT.UserMnemonicID = A.AssignedTo
WHERE A.StatusID NOT IN ('Complete','Open')
)
select id,date from cte where rn=1
Upvotes: 0
Reputation: 1269563
I think you just want aggregation:
SELECT A.ID, MAX(C.Date)
FROM IDTable A INNER JOIN
AccountTable B
ON B.AccountID = A.AccountID FULL OUTER JOIN
Updates U
ON U.ID = A.ID FULL OUTER JOIN
Update2 C
ON C.AccountID = B.AccountID INNER JOIN
UserTable UT
ON UT.UserMnemonicID = A.AssignedTo
WHERE A.StatusID NOT IN ('Complete', 'Open')
GROUP BY A.ID;
I have no idea why you would be using FULL OUTER JOIN
, much less why you would be mixing them with INNER JOIN
. I suspect you really want LEFT JOIN
.
Upvotes: 0