SQL-按多个顺序转换行数函数

SQL-按多个顺序转换行数函数,sql,sql-server,Sql,Sql Server,我正在尝试将此查询转换为不带行号函数的子查询: SELECT InvestorFundId, AsOfDate, AddedOn FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY InvestorFundId ORDER BY AsOfDate DESC, AddedOn DESC) AS HistoryIndex, * FROM [Investor.Fund.History]

我正在尝试将此查询转换为不带
行号
函数的子查询:

 SELECT InvestorFundId, AsOfDate, AddedOn FROM (
   SELECT ROW_NUMBER() OVER (PARTITION BY InvestorFundId ORDER BY AsOfDate DESC, AddedOn DESC) AS HistoryIndex, *
                      FROM   [Investor.Fund.History]
                      WHERE  DataStatusId = 1 AND AsOfDate <= (SELECT PeriodDate FROM [Fund.Period] WHERE Id = 5461)
                      ) G WHERE HISTORYINDEX = 1
我的查询给出了不正确的结果,这是因为当我对多列使用
MAX
函数时,它不会像行号那样根据两列的顺序选择MAX,而是选择
MAX
,无论两列的顺序位置如何

例如,如果我有如下数据子集:

 | InvestorFundId |          AsOfDate       |           AddedOn         |
 |  1             | 2010-10-01 00:00:00.000 |   2012-04-18 09:29:33.277 |
 |  1             | 2006-11-01 00:00:00.000 |   2013-04-18 11:25:23.033 |
ROW_NUMBER函数将返回以下内容:

  |  1             | 2010-10-01 00:00:00.000 |   2012-04-18 09:29:33.277 |
而我的函数返回:

 |  1             | 2010-10-01 00:00:00.000 |   2013-04-18 11:25:23.033 |
如您所见,它实际上不是表中的一行

我希望函数根据
MAX
AsOfDATE
AddedOn
正确返回表中的行


有人能帮忙吗?

如果您有一个唯一的id来标识每一行,那么您可以执行以下操作:

WITH ifh as (
      SELECT InvestorFundId, AsOfDate, AddedOn
      FROM [Investor.Fund.History]
      WHERE DataStatusId = 1 AND AsOfDate <= (SELECT PeriodDate FROM [Fund.Period] WHERE Id = 5461)
     )
SELECT ifh.*
FROM ifh
WHERE ifh.? = (SELECT ?
               FROM ifh ifh2
               WHERE ifh2.InvestorFundId = ifh.InvestorFundId
               ORDER BY AsOfDate DESC, AddedOn DESC
               FETCH FIRST 1 ROW ONLY
              );

UH你想改变这一切有什么原因吗?使用ROW_NUMBER()是这样做的标准。@ZLK我刚开始在一家新公司工作,他们想删除ROW_NUMBER函数,但他们说这不是优化的结果。。。好像他们没有索引?我不确定这里没有优化的
意味着什么。实际上,您编写的任何查询都必须遍历每个组,并根据条件选择一行。有些情况下,
APPLY
或下面gordon的答案可能会更快,但也可能比row_number()排序慢。@ZLK它们确实在表上有索引,我确信它们缺少一些,尽管我认为第一个建议不是值sql,但第二个是值sql。尽管我刚刚检查过,您的建议使用了与原始查询相比批次的99%的查询成本
WITH ifh as (
      SELECT InvestorFundId, AsOfDate, AddedOn
      FROM [Investor.Fund.History]
      WHERE DataStatusId = 1 AND AsOfDate <= (SELECT PeriodDate FROM [Fund.Period] WHERE Id = 5461)
     )
SELECT ifh.*
FROM ifh
WHERE ifh.? = (SELECT ?
               FROM ifh ifh2
               WHERE ifh2.InvestorFundId = ifh.InvestorFundId
               ORDER BY AsOfDate DESC, AddedOn DESC
               FETCH FIRST 1 ROW ONLY
              );
select ifh2.*
from (select distinct InvestorFundId
      from ifh
     ) i cross apply
     (select top (1) ifh2.*
      from ifh ifh2
      where fh2.InvestorFundId = i.InvestorFundId
      order by AsOfDate DESC, AddedOn DESC
      fetch first 1 row only
     ) ifh2;