简体   繁体   中英

SQL - where date = max date

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

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

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 .

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

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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM