如何从SQL加入3个表中选择最新数据?

时间:2017-09-02 14:48:26

标签: sql sql-server join group-by

我有3张桌子。我需要通过列RANKDATA从(DATA表)加入(AGENT表)。 DATA表中可能有多个条目。我需要根据DATE选择最新的,然后获取CODE_ID并加入CODE表。

problem

这是我的代码。我试图使用Max(D.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

output

2 个答案:

答案 0 :(得分:0)

我不清楚您的图片应该是什么结果,而使用group by执行此操作的替代方法可能是使用row_numberrow_number基本上在您的行上投射一个递增整数(1,2,3,... n)的列。你可以"分区"功能与您分组的方式相同。在这种情况下,我将其按a.RankData分区,但这有点猜测你想要什么。 order by定义行编号的显示顺序。在这种情况下,我已按d.[date]降序排序,因此每个a.RankData的最新日期将为数字1.最后,我将所有这些转换为子查询,以便我可以将where子句中的新列,只是略去那些RID = 1(即日期是最大日期)的列。

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

答案 1 :(得分:0)

您可以尝试使用CROSS APPLY作为附加选项。

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

图像有助于可视化。但是如果您需要其他人的时间来帮助您,那么如果您包含一个简单的脚本来创建测试数据肯定会有用: 像这样:

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')