代码之家  ›  专栏  ›  技术社区  ›  Andrew

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

  •  0
  • Andrew  · 技术社区  · 6 年前

    我正在尝试将此查询转换为不带 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 函数在多列上运行时,它不会像行号那样根据两列的顺序选择最大值,而是选择 马克斯

    例如,如果我有一个如下所示的数据子集:

     | 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\u 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 |
    

    如您所见,它实际上不是表中的一行。

    我希望函数根据 AsOfDATE 以及 AddedOn

    有人能帮忙吗?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Gordon Linoff    6 年前

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