Reputation: 47
I have 3 tables. I need to join the (AGENT table) from (DATA table) by column RANKDATA. There may be multiple entries in the DATA table. I need to select the most recent based on the DATE, then get the CODE_ID and join in CODE table.
Here's my code. I tried to use Max(D.DATE)
but I got an error. My only problem, I don't know how to group it by the most recent date.
select A.ID, A.NAME, C.CODE_NAME, D.DATE
from Agent A
JOIN Data D ON A.RANKDATA = D.RANKDATA
JOIN CODE C ON D.CODE_ID = C.CODE_ID
Upvotes: 0
Views: 159
Reputation: 473
You could try using a CROSS APPLY, as an additional option.
SELECT A.ID, A.NAME, T.CODE_NAME, T.DATE
FROM Agent A
CROSS APPLY
(SELECT TOP 1 C.CODE_NAME, D.DATE
FROM
Data D JOIN CODE C ON D.CODE_ID = C.CODE_ID
WHERE A.RANKDATA = D.RANKDATA
ORDER BY D.DATE DESC) T
An image helps to visualize. But if you need time from others to help you, it would definitely be useful if you include a simple script to create your test data: Something like this:
CREATE TABLE Agent (ID INT, NAME VARCHAR(30) ,RANKDATA INT)
INSERT INTO Agent
VALUES (1,'Mark',12), (2,'Joe',13), (3,'Steve',11), (4,'Sam',10)
CREATE TABLE DATA (ID int, RANKDATA int, CODE_ID VARCHAR(2), DATE datetime)
INSERT INTO DATA
VALUES (1,12,'01','20170901 2:30'), (2,13,'02','20170901 6:30'),
(3,11,'03','20170901 4:30'), (4,10,'02','20170901 1:30'),
(5,10,'03','20170901 2:50'), (6,12,'02','20170901 5:30')
CREATE TABLE CODE(ID int, CODE_ID varchar(2), CODE_NAME Varchar(15))
INSERT INTO CODE
VALUES (1,'01','RANK 1'), (2,'02','RANK 2'), (3,'03','RANK 3')
Upvotes: 0
Reputation: 4695
I'm not quite clear on what your results are supposed to be from your image, bu t an alternative to doing this with a group by
might be to use row_number
. row_number
basically projects a column with an incrementing integer (1,2,3,...n) over your rows. You can "partition" the function in the same way you would a group by. In this case, I partitioned it by a.RankData
, but that was sort of a guess at what you wanted. The order by
defines in what order the row numbering will appear. In this case, I've ordered it by d.[date]
descending so the most recent date for every a.RankData
will be the number 1. Finally, I turn all that into a subquery so I can put the new column in a where
clause and just skim off those where RID = 1
(i.e the date is the max date).
select *
from (select
RID = row_number() over(partition by a.RankData order by d.[date] desc),
A.ID,
A.NAME,
C.CODE_NAME,
D.DATE
from Agent A
inner join [Data] D
on A.RANKDATA = D.RANKDATA
inner join CODE C
on D.CODE_ID = C.CODE_ID) a
where a.RID = 1
Upvotes: 0