从多联接中选择包含最新日期的行

时间:2018-04-26 01:30:32

标签: sql sql-server

我无法从多连接语句中获取带有最新日期的第1行。

涉及3个表:

(单位)

SN                |            DateTime |
------------------|---------------------|
123               |2018-03-10 15:23:32  |
456               |2018-03-10 15:40:15  |
789               |2018-03-10 15:53:58  |

(历史)

ID     |SN                |
-------|------------------|
84     |123               |
85     |456               |
86     |789               |

(链路)

SN                |      ID |
------------------|---------|
123               |84       |
456               |85       |
789               |86       |

(站)

ID     |Type            |      datetime      |location                 |
-------|----------------|--------------------|-------------------------|
84     |ALPHA           |2017-08-21 16:54:23 |X                        |
84     |BRAVO           |2017-08-21 16:56:08 |X1                       |
277    |DELTA           |2017-08-21 17:46:11 |Y                        |

目标

获取一个联接表,该表仅显示每行具有最新日期时间并且已选择类型的行。

我已设法加入表格,甚至对日期时间进行排序,以便最近的日期总是排在前1位,但我不知道如何选择我感兴趣的前1名。

我现在已经在这几天没有了,只能得到我需要的那一行。我总是最终得到重复的信息,例如(Station)ID 84。

我之前尝试过的内容

SELECT rs.Unit, max(rf2.Type) as mydate,  rf2.Type, rf2.ID
FROM DB.dbo.Unit rs 
INNER JOIN DB.dbo.Link rf ON ( rs.ID = rf.ID  )  
INNER JOIN DB.dbo.History rf1 ON ( rf.SN = rf1.SN)  
INNER JOIN DB.dbo.Station rf2 ON ( rf1.ID = rf2.ID )         
where rf2.Type like 'AL%'
GROUP BY rs.SN, rf2.DateTime, rf2.Type, rf2.ID
order by rs.SN, rf2.DateTime desc;

我也尝试过CTE,但同样的问题:我不知道如何只保留最近的行。

上述结果

SN                |mydate               |Type         |ID     |
------------------|---------------------|-------------|-------|
666               |2017-09-23 15:15:58  |Alpha        |189    |
777               |2017-09-01 16:13:16  |Alpha7       |138    |
*123*             |*2017-11-03 09:17:51*|*Alpha1*     |*84*   |
123               |2017-11-01 03:08:09  |Alpha2       |84     |
123               |2017-11-01 03:07:59  |Alpha3       |84     |

基本上我需要的是一个只保留唯一行的表格,例如标有星号的行( 123 ),最近的日期,特定类型如'喜欢&#39 ; AL%'

在@Ferc的评论后,我试过这样的事情:

select ts.ID, ts.DateTime, ts.location 
from (select ID, DateTime, location 
row_number() over(partition by ID order by DateTime desc) as rn
from DB.dbo.Station where station like 'AL%') as ts
where rn = 1; 

I got "SQL Error [102] [S0001]: Incorrect syntax near '('.
Incorrect syntax near '('.
Incorrect syntax near '('." 
as an (complete rubbish) error message.

然后我放了一个','在 location 之后得到了一个结果。

我会尝试将其纳入我的CTE。

2 个答案:

答案 0 :(得分:2)

select * from (
    select 
    row_number() over(partition by rf2.[datetime] order by rf2.[datetime] desc) as rn 
    ,rf2.*
    FROM Unit rs 
    INNER JOIN Link rf ON ( rs.SN = rf.SN  )  
    INNER JOIN History rf1 ON ( rf.SN = rf1.SN)  
    INNER JOIN Station rf2 ON ( rf1.ID = rf2.ID )  
    where rf2.Type like 'AL%'
) T
where rn = 1;

SQL Fiddle Example Link

答案 1 :(得分:0)

如果我理解正确,你可能会这样做。

您需要使用ROW_NUMBER编写一个带有OVER(partition by rf2.ID,rs.SN order by rf2.[datetime] desc)的子查询,您将获得rf2.IDrs.SN上的组编号。

然后获取RowNumber = 1行,这意味着最新的日期。

SELECT t.SN,t.[datetime],t.Type,t.ID
FROM(
  SELECT rs.SN,
         rf2.[datetime],
         rf2.[Type],
         rf2.ID,
         ROW_NUMBER() OVER(partition by rf2.ID,rs.SN order by rf2.[datetime] desc) rn
  FROM Unit rs 
  INNER JOIN Link rf ON ( rs.SN = rf.SN  )  
  INNER JOIN History rf1 ON ( rf.SN = rf1.SN)  
  INNER JOIN Station rf2 ON ( rf1.ID = rf2.ID )         
  WHERE rf2.Type like 'AL%'
) t 
where t.rn = 1

sqlfiddle:http://sqlfiddle.com/#!18/36061/2