【问题标题】:Join table with current year and get prior year records加入当前年份的表并获取上一年的记录
【发布时间】:2020-10-07 23:03:04
【问题描述】:

输入

表A

ID  YEAR    
101 2012
101 2013
101 2014
102 2012
102 2013
102 2014

表B

ID  YEAR    AMOUNT
101 2011    2384
101 2012    2987
101 2013    3232
101 2014    3987
102 2011    2212
102 2012    2332
102 2013    2987
102 2014    3222

输出表

ID  YEAR    AMOUNT  PREV YEAR AMOUNT
101 2012    2987    2384
101 2013    3232    2987
101 2014    3987    3232
102 2012    2332    2212
102 2013    2987    2332
102 2014    3222    2987

问题描述:TableA 将选择年份作为基数,tableB 将拥有所有记录,但我需要连接 tableA 和 TableB 以连接上一年的数据,请参阅输出表。我尝试了自我加入,但无法获得它。

【问题讨论】:

  • 请在代码问题中给出minimal reproducible example--cut & paste & runnable code,包括最小的代表性示例输入作为代码;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。给出尽可能少的代码,即您显示的代码可以通过您显示的代码扩展为不正常的代码。 (调试基础。)对于包含 DBMS 和 DDL(包括约束和索引)和输入为格式化为表的代码的 SQL。 How to Ask 暂停总体目标的工作,将代码砍到第一个表达式,没有给出你期望的内容,说出你期望的内容和原因。
  • 不同年份同一个id? Id是你的PK吗?我必须承认我很难理解这个场景。

标签: sql sql-server tsql date join


【解决方案1】:

我认为这是两个连接:

select a.*, b.amount, bprev.amount
from a left join
     b
     on b.id = a.id and b.year = a.year left join
     b bprev
     on bprev.id = a.id and bprev.year = a.year - 1;

Here 是一个 dbfiddle。

【讨论】:

  • 如果我做左连接,我会从输出表中的tableB获取所有记录,我们需要使用连接而不是左连接吗?
  • @Ashik 。 . . left join 将所有表格保存在 a 中,而不是 b 中(参见小提琴)。您可以使用join,但如果年份是数据中的第一年或缺少年份,它将过滤行。
【解决方案2】:

如果你们IDs 都有所有年份的数据,你可以只使用窗口函数。这应该比自连接更有效,因为它只扫描tableb 一次:

select b.*
from tablea a
inner join (
    select b.*, lag(amount) over(partition by id order by year) prev_year_amount
    from tableb b
) a on a.id = b.id and a.year = b.year

【讨论】:

  • 是的,没错,但我们没有所有年份的数据,可能有破损。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-24
相关资源
最近更新 更多