基于日期

时间:2017-06-11 18:51:42

标签: sql-server

我之前发布了此查询。再次发布更多细节,以帮助更好地理解我的问题

原始数据集

Name          currency  lcfeerate   effectivestartdate
Institution1    USD      0.0029      7/9/2009
Institution1    CAD      0.0029      7/9/2009
Institution1    USD      0.0034      4/3/2017
Institution2    CAD      0.0029      7/9/2009
Institution2    USD      0.0029      7/9/2009
Institution3    CAD      0.0029      7/9/2009
Institution3    USD      0.0029      7/9/2009
Institution3    USD      0.0034      4/3/2017
Institution3    CAD      0.0034      4/3/2017

我需要运行查询,例如返回每个对应于每个机构和相应货币的一行。即Institution1将有2行,每行1美元和CAD。同样,机构2和3各有2行。因此最终结果是一个6行的表。 过滤表的规则是,对于每个机构和货币,lcfeerate是根据effectivestartdate选择的。 当effectivestartdate位于声明的startdate和enddate之间时,则为该有效的startartate选择feerate。如果声明的startdate和enddate之间没有有效的启动,则它会检查先前的最大有效开始时间。 以下是所需输出的两个示例。 例1

Start date- 1/1/2017        
End date-   3/31/2017       
Name         currency   lcfeerate   effectivestartdate
Institution1    USD      0.0029        7/9/2009
Institution1    CAD      0.0029        7/9/2009
Institution2    CAD      0.0029        7/9/2009
Institution2    USD      0.0029        7/9/2009
Institution3    CAD      0.0029        7/9/2009
Institution3    USD      0.0029        7/9/2009

由于申报的开始日期和结束日期之间没有有效的开始日期,它会选择下一个可用的有效开始日期为7/9/2009,并提供与每个机构的日期相对应的lcfeerate以及货币USD和CAD。

示例2

Start date- 4/1/2017        
End date-   5/31/2017       
Name         currency   lcfeerate   effectivestartdate
Institution1    CAD       0.0029      7/9/2009
Institution1    USD       0.0034      4/3/2017
Institution2    CAD       0.0029      7/9/2009
Institution2    USD       0.0029      7/9/2009
Institution3    USD       0.0034      4/3/2017
Institution3    CAD       0.0034      4/3/2017

在这种情况下,因为对于机构3,4/3/2017的有效开始位于声明的startdate和enddate之间,它为它提供了新的lcfeerates。对于机构1,美元汇率在宣布的日期之间有效开始,因此提供一个,其余3行在宣布的日期之间没有有效的开始,因此选择前一个有效的开始提供lcfeerate。

根据有效的开始和按名称和货币分组来排序表非常容易以获得最高值,但我有条件我不知道如何编写此查询。

我试过的查询是:

declare @startdate as datetime = '1-Jan-2017';
declare @enddate as datetime = '31-Mar-2017';

select bankname, lcfeerate
        ,case when effectivestartdate between @startdate and @enddate then lcfeerate 
           when effectivestartdate not between @startdate and @enddate
        then (select *
        from (
              select *, row_number()
              over (partition by name, currency order by effectivestartdate desc) as seqnum
                from table1
             ) t1
        where seqnum = 1)end as lcfeerate
     from table1

我收到以下错误:

  

当选择列表中只能指定一个表达式时   子查询不是用EXISTS引入的。

2 个答案:

答案 0 :(得分:0)

你非常接近,但你排名错了。第一个排名标准应该是日期是否在日期范围内,第二个是日期是否按降序排列。

select name, currency, lcfeerate, effectivestartdate
from
(
  select 
    name, currency, lcfeerate, effectivestartdate, 
    row_number() over (partition by name, currency order by
          case when effectivestartdate between @startdate and @enddate the 1 else 2 end,
          effectivestartdate desc) as rn
  from table1
) ranked;

答案 1 :(得分:0)

Wrapper*

我希望它对你有所帮助。