Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL:选择每个组中返回多条记录的前1个组_Sql_Sql Server - Fatal编程技术网

SQL:选择每个组中返回多条记录的前1个组

SQL:选择每个组中返回多条记录的前1个组,sql,sql-server,Sql,Sql Server,我有一张这样的桌子: | Id | InvestorFundId | Name | AccountKey | AsOfDate | AddedOn | | 1 | 11111 | Name1| Key1 | 9/5/2018 | 8/5/2018 | | 2 | 11111 | Name2| Key1 | 9/3/2018 | 8/5/2018 | | 3 | 22222 | Name3| Key2

我有一张这样的桌子:

| Id | InvestorFundId | Name | AccountKey | AsOfDate | AddedOn  |
| 1  | 11111          | Name1| Key1       | 9/5/2018 | 8/5/2018 |
| 2  | 11111          | Name2| Key1       | 9/3/2018 | 8/5/2018 |
| 3  | 22222          | Name3| Key2       | 9/2/2018 | 8/5/2018 |
| 4  | 33333          | Name4| Key3       | 9/2/2018 | 8/5/2018 |
| 5  | 33333          | Name5| Key3       | 9/4/2018 | 8/5/2018 |
| InvestorFundId | Name | AccountKey |
| 11111          | Name1| Key1       | 
| 22222          | Name3| Key2       |
| 33333          | Name5| Key3       | 
我需要能够根据排序的
AsOfDate
AddedOn
降序返回每组最近的
InvestorFundId
、姓名和
AccountKey

预期结果应如下所示:

| Id | InvestorFundId | Name | AccountKey | AsOfDate | AddedOn  |
| 1  | 11111          | Name1| Key1       | 9/5/2018 | 8/5/2018 |
| 2  | 11111          | Name2| Key1       | 9/3/2018 | 8/5/2018 |
| 3  | 22222          | Name3| Key2       | 9/2/2018 | 8/5/2018 |
| 4  | 33333          | Name4| Key3       | 9/2/2018 | 8/5/2018 |
| 5  | 33333          | Name5| Key3       | 9/4/2018 | 8/5/2018 |
| InvestorFundId | Name | AccountKey |
| 11111          | Name1| Key1       | 
| 22222          | Name3| Key2       |
| 33333          | Name5| Key3       | 
我查看了一些帖子,但我无法正确返回行,以下是我到目前为止得到的信息:

SELECT Name, AccountKey, H.InvestorFundId FROM
[Investor.Fund.History] H
CROSS APPLY(SELECT TOP 1 InvestorFundId 
FROM [Investor.Fund.History] 
WHERE  DataStatusId = 1 AND AsOfYearMonth <= 201806
ORDER BY AsOfDate DESC, AddedOn DESC) HS
ORDER BY H.InvestorFundId
从中选择名称、AccountKey、H.InvestorFundId
[Investor.Fund.History]H
交叉应用(选择前1名InvestorFundId
来自[投资者、基金、历史]

当DataStatusId=1且为一个月时,您可以将
与TIES一起使用
,只需将
行数
应用于
排序依据

Select top 1 with ties *
From History
Where DataStatusId = 1 and AsOfYearMonth = 201806
Order by 
Row_Number() over (partition by InvestorFundID order by AsOfDate desc)
或者使用子查询

Select  *
    From (select * , RN= Row_Number() over (partition by InvestorFundID order by AsOfDate desc)
             From History
             Where DataStatusId = 1 and AsOfYearMonth = 201806) x
Where x.RN = 1
如果您发现速度变慢,那么我们需要查看执行计划以确定速度变慢的原因。InvestorFundId上的非聚集索引AsOfDate desc将使速度变得非常快

Create nonclustered index indexName on
History (InvestorFundID, AsOfDate desc)

您可以使用CTE获取所需的数据

USE tempdb;
GO

DECLARE @table TABLE (Id INT IDENTITY(1, 1), InvestorFundId INT, Name VARCHAR(50), AccountKey VARCHAR(50), AsOfDate DATE, AddedOn DATE);
INSERT INTO @table VALUES (11111, 'Name1', 'Key1', '9/5/2018', '8/5/2018');
INSERT INTO @table VALUES (11111, 'Name2', 'Key1', '9/3/2018', '8/5/2018');
INSERT INTO @table VALUES (22222, 'Name3', 'Key2', '9/2/2018', '8/5/2018');
INSERT INTO @table VALUES (33333, 'Name4', 'Key3', '9/2/2018', '8/5/2018');
INSERT INTO @table VALUES (33333, 'Name5', 'Key3', '9/4/2018', '8/5/2018');

;WITH CTE AS
(
    SELECT InvestorFundId, Name, AccountKey, ROW_NUMBER() OVER (PARTITION BY InvestorFundID ORDER BY AsOfDate DESC) AS RowId FROM @table
)
SELECT InvestorFundId, Name, AccountKey
    FROM CTE
    WHERE RowId = 1;
这是一张工作票


希望能有所帮助。

很抱歉,行号太慢,但对于这个问题,这将是每次都正确的答案。当然应该比交叉应用程序查询快,你能发布行号查询吗,因为可能只是出了点问题。除此之外,还可以使用正确的索引进行改进。我的想法正是@TomCGood alterActive尽管快速测试显示这比CTE版本慢很多,不管有没有索引。我必须测试,但我仍然在CTE上使用子查询。添加了该版本为什么?在这种情况下,CTE的计算结果将与嵌套子查询的执行计划完全相同。只是一个更整洁的查询。可能是其中之一但这取决于个人偏好。因为在非复杂查询中,CTE可能会产生您意想不到的结果。这个问题有点离题,但常见的情况是在CTE中对单个谓词进行过滤,例如列=1,列为varchar,然后在后续选择中转换此列。您可以获得由于CTE应该“过滤”这一点,所以不应该出现转换错误。虽然这种情况很少出现,而且只在简单的CTE查询中出现,但也有一些例子。