SQL-用

时间:2018-09-10 21:50:50

标签: sql sql-server

我正在尝试将此查询转换为不具有ROW_NUMBER函数的子查询:

 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

基本上,这是在一段时间内根据状态选择最近的[Investor.Fund.History]

到目前为止,我有这个:

SELECT InvestorFundId, MAX(AsOfDate) AS MaxAsOfDate, MAX(AddedOn) AS MaxAddedOn FROM [Investor.Fund.History]
WHERE DataStatusId = 1 AND AsOfDate <= (SELECT PeriodDate FROM [Fund.Period] WHERE Id = 5461)
GROUP BY InvestorFundId

我的查询给出了不正确的结果,并且这样做是因为当我在多列上使用MAX函数时,它没有像ROW_NUMBER那样基于两列的顺序选择最大值,而是选择了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 AsOfDATEAddedOn

正确返回表中的行。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

如果您具有标识每一行的唯一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
              );

?用于唯一标识每一行的列。

这也可以使用APPLY来完成:

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;