表内连接本身

时间:2017-07-13 20:24:54

标签: sql sql-server join

我有一个包含3列(代码,状态,日期)的表,它记录了代码状态的历史记录,每个代码可能已多次更改状态。

我想显示每个代码的最后状态我所做的就像这样

SELECT code,MAX(date), .... 
FROM table 
GROUP BY code.

我不知道该准备什么来获得这个州。我试图只是放置状态,因此它获得对应于code,max(date)组合的状态,但它给出了错误,即不在聚合函数中。

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:2)

如果我了解你有

等数据
CODE  State  Date
1     IL     1/1/2016
1     IA     1/1/2017
1     AL     1/1/2015

您希望在结果中看到

1 IA 1/1/2017

使用窗口函数和公用表表达式(with):我们根据日期降序为每个代码分配一个行号,并仅为每个代码返回第一行。

With CTE AS (SELECT code
           , date
           , state
           , Row_number() over (partition by code order by date desc) RN
             FROM table )
SELECT Code, Date, State 
FROM CTE 
WHERE RN =1

使用子查询:(我们获取每个代码的最大日期,然后联接回基本集以限制返回的行。

SELECT A.code, A.date, A.state
FROM table  A
INNER JOIN (SELECT max(date) mdate, code 
            FROM table 
            GROUP BY code) B
 on A.Code = B.Code
and A.Date = B.MDate

当窗口函数不可用时,使用后面的查询。解决问题的现代方法是使用第一种方法。

实质上,第一个查询的作用是根据日期降序为每个代码分配#1到x。因此,每个代码的最大日期获得的RN为1。因此,当我们说RN = 1时,我们只返回具有相关代码的最大日期的代码/状态/记录。我们使用with语句,因为我们需要RN实现(实际上在内存中生成),以便我们可以在with(公用表表达式)查询的第二部分中限制它。 / p>

答案 1 :(得分:1)

如果您正在进行汇总,例如MAX(),那么您选择的所有其他非汇总列也需要位于GROUP BY。这就是为什么当您仅将state添加到选择内容时,您会收到错误的原因。如果您将其添加到select和group中,您将获得结果:

SELECT State, Code, MAX(Date)
FROM table
GROUP BY State, Code

答案 2 :(得分:1)

如果您想要在帖子中提及内部联接,请使用匹配的codedate

将内部联接返回给自己
SELECT * 
FROM table t1
INNER JOIN  (SELECT code,MAX(date)
             FROM table 
             GROUP BY code) codeWithLatestDate ON t1.code = codeWithLatestDate.code AND t1.date = codeWithLatestDate.dat3

但我建议您在state条款和GROUP BY cluase

中添加SELECT
SELECT code,MAX(date),state
FROM table 
GROUP BY code, state

答案 3 :(得分:1)

你可以通过加入自身

来做到这一点
SELECT State,Code,Date
FROM table t
JOIN (
SELECT  Code, MAX(Date) as Date
FROM table
GROUP BY  Code) t1 on t1.Code= t.Code and t.Date=t1.Date