SQL查询显示来自同一个表的差异

cat*_*hat 3 sql join

我的应用程序有一个表,其中包含每年的快照库存数据.例如,存在具有典型列vehicle_id,vehicle_plate_num,vehicle_year,vehicle_make等的车辆库存表,而且还指示车辆所拥有的年份.

查询整个表可能会导致如下所示:

Id  Plate Num   Year Make     Model    Color   Year Owned
---------------------------------------------------------
1   AAA555      2008 Toyota   Camry    blue    2009
2   BBB666      2007 Honda    Accord   black   2009
3   CCC777      1995 Nissan   Altima   white   2009
4   AAA555      2008 Toyota   Camry    blue    2010
5   BBB666      2007 Honda    Accord   black   2010
6   DDD888      2010 Ford     Explorer white   2010
Run Code Online (Sandbox Code Playgroud)

(好的或坏的,这个表已经存在,它不是重新设计表的选项,这是另一个问题的主题).你在这里看到的是年复一年,大多数车辆仍然在库存中,但总是有旧的车辆摆脱的情况,并且新的车辆被收购.在上面的例子中,1995年的日产Altima在2009年的库存中,但不再是2010年的库存.2010年的库存有一个新的2010福特Explorer.

如何构建一个有效查询,需要两年时间才能显示差异.例如,如果我在2009年,2010年通过,则应返回查询

3   CCC777  1995  Nissan  Altima      white   2009
Run Code Online (Sandbox Code Playgroud)

如果我在2010年,2009年通过,则应返回查询

6   DDD888   2010  Ford   Explorer   white   2010
Run Code Online (Sandbox Code Playgroud)

编辑:我应该在Kyle B.的回答后添加评论,但评论的文本区域不是非常用户友好:

我认为这不会很难,但似乎是这样.

无论如何,你不需要从上面的子选择像这样:

select q.* from (
    select f.*
    from inventory f 
      left join inventory s
      on (f.plate_num = s.plate_num 
         and f.year_owned = :first-year
         and s.year_owned = :second-year)
    where s.plate_num is null
) q
where q.year_owned = :second_year
Run Code Online (Sandbox Code Playgroud)

Kyl*_*utt 5

你想要一个自我加入的联盟

看起来你想要不对称的差异.如果您想要对称差异,则可以使用完全外连接而不是左(或右)外连接.

随变量:第一年和第二年

select f.*
   from inventory f 
     left join inventory s
        on (f.plate_num = s.plate_num
           and s.year_owned = :second-year)
where s.plate_num is null 
  and f.year_owned = :first-year
Run Code Online (Sandbox Code Playgroud)

请注意,条件必须在连接条件内,以便数据库在没有匹配时返回空行,而不是找到稍后通过过滤删除的匹配.

编辑:略微调整查询.这不需要子选择.用postgresql测试.