通过聚合加入 table 本身
Joining a table on itself with aggregation
我正在尝试(有效地)从连接 table 获取行,其中开始日期是 cpid 中最新的 - 对于选定的 cpid。
这是连接 table 中的数据示例,其中我希望用 <<<
标记的行
connid cpid startdate
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 <<<
etc...
此查询 returns 最新的开始日期和 cpid,但我不确定如何将其与自身连接以获得我需要的结果:
select cpid, max(startdate)
from connections
where cpid in (
20,
30,
40
)
group by cpid
我要找的结果如下:
connid cpid startdate
3 20 9/12/16
5 30 8/23/16
8 40 5/18/16
如有任何帮助,我们将不胜感激!
罗姆
像这样:
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)
这是一个使用 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
我正在尝试(有效地)从连接 table 获取行,其中开始日期是 cpid 中最新的 - 对于选定的 cpid。
这是连接 table 中的数据示例,其中我希望用 <<<
标记的行connid cpid startdate
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 <<<
etc...
此查询 returns 最新的开始日期和 cpid,但我不确定如何将其与自身连接以获得我需要的结果:
select cpid, max(startdate)
from connections
where cpid in (
20,
30,
40
)
group by cpid
我要找的结果如下:
connid cpid startdate
3 20 9/12/16
5 30 8/23/16
8 40 5/18/16
如有任何帮助,我们将不胜感激!
罗姆
像这样:
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)
这是一个使用 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