我正在尝试(有效地)从连接表中获取行,其中startdate是cpid中的最新行 - 对于选定的cpid来说。
这是一个连接表中数据的示例,其中我想要标记为<<<<
的行select cpid, max(startdate)
from connections
where cpid in (
20,
30,
40
)
group by cpid
此查询返回最新的startdate和cpid,但我不确定如何将其与自身连接以获得我需要的结果:
connid cpid startdate
3 20 9/12/16
5 30 8/23/16
8 40 5/18/16
我正在寻找的结果如下:
local[*]
任何帮助将不胜感激! ROBM
答案 0 :(得分:5)
这样的事情:
WITH Numbered AS
(
SELECT ROW_NUMBER() OVER(PARTITION BY cpid ORDER BY startdate DESC) AS Nr
,*
FROM connections
)
SELECT *
FROM Numbered
WHERE Nr=1;
函数ROW_NUMBER()
将为行添加一个运行编号。 PARTITION BY
允许您重新启动组的运行编号,ORDER BY
允许您定义编号的顺序。使用DESC
,您将获得最新信息,因此Nr = 1。
如果你需要在除SQL-Server之外的其他系统上使用它,你可能会采用老式的方式:
SET DATEFORMAT mdy;
DECLARE @tbl TABLE(connid INT, cpid INT, startdate DATE);
INSERT INTO @tbl VALUES
( 1,20,'7/17/16')
,(2,20,'8/23/16')
,(3,20,'9/12/16')
,(4,30,'6/17/16')
,(5,30,'8/23/16')
,(6,40,'2/24/16')
,(7,40,'3/17/16')
,(8,40,'5/18/16') ;
SELECT *
FROM @tbl AS tbl
WHERE tbl.startdate IN(SELECT MAX(x.startdate) FROM @tbl AS x WHERE x.cpid=tbl.cpid)
答案 1 :(得分:1)
这是使用CROSS APPLY而不是CTE的替代解决方案,执行计划是不同的,一旦您在您的环境中尝试它,它可能会更有效。
DROP TABLE #connections
CREATE TABLE #connections(connid INT, cpid INT,startdate datetime)
INSERT INTO #connections(connid,cpid,startdate)
VALUES
(1,'20','20160717')
,(2,'20','20160823')
,(3,'20','20160912')
,(4,'30','20160617')
,(5,'30','20160823')
,(6,'40','20160224')
,(7,'40','20160317')
,(8,'40','20160518')
SELECT
c.connid,c.cpid,c.startdate
FROM
#connections c
CROSS APPLY (
SELECT
cpid
,MAX(startdate) startdate
FROM
#connections
GROUP BY
cpid
) a
WHERE
c.cpid = a.cpid
AND c.startdate = a.startdate