SQL - 使最大生效日期小于另一个表中的日期

时间:2010-07-19 20:39:09

标签: sql

我目前正在开发一个转换脚本,用于将一堆旧数据从SQL Server 2000数据库转移到SQL Server 2008上。我在转换过程中想要完成的一件事就是消除所有复合键,并用“适当的”主键替换它们。显然,当我传输数据时,我需要将外键值注入新的表结构中。

我目前仍然坚持使用一个数据集,而我似乎无法以基于集合的方式解决它。我工作的两张桌子叫做Charge and Law。它们在三列上具有1:1的关系和“链接”。前两个是LawSource和LawStatue列上的相同链接,但第三列引起了我的问题。 ChargeDate列应链接到LawDate< = ChargeDate。

的LawDate列

我当前的查询为给定的Charge返回多行(在某些情况下),因为Law可能有多个LawDate小于或等于ChargeDate。

以下是我目前的情况:

select LawId
from Law a
join Charge b on b.LawSource = a.LawSource 
                 and b.LawStatute = a.LawStatute 
                 and b.ChargeDate >= a.LawDate

我可以用任何方式重写这个以获取法律表中与ChargeDate相同(或更早)日期的最新条目吗?

2 个答案:

答案 0 :(得分:2)

在SQL 2008中使用分区功能会更容易(因此,将来应该会更容易)。

通常的警告“我没有你的架构,因此未经测试”适用,但我认为它应该做你需要的。

select
  l.LawID
from
  law l
  join (
    select 
      a.LawSource,
      a.LawStatue,
      max(a.LawDate) LawDate
    from 
      Law a
      join Charge b on b.LawSource = a.LawSource 
                     and b.LawStatute = a.LawStatute 
                     and b.ChargeDate >= a.LawDate
    group by
      a.LawSource, a.LawStatue
  ) d on l.LawSource = d.LawSource and l.LawStatue = d.LawStatue and l.LawDate = d.LawDate

答案 1 :(得分:1)

如果性能不是问题,cross apply提供了一种非常易读的方式:

select  *
from    Law l
cross apply
        (
        select  top 1 *
        from    Charge
        where   LawSource = l.LawSource 
                and LawStatute = l.LawStatute 
                and ChargeDate >= l.LawDate
        order by
                ChargeDate
        ) c

对于每一行,这将使用最小的ChargeDate查找Charge表中的行。

要包含来自Law的行而不匹配Charge,请将cross apply更改为outer apply