我的应用程序有一个表,其中包含每年的快照库存数据.例如,存在具有典型列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)
看起来你想要不对称的差异.如果您想要对称差异,则可以使用完全外连接而不是左(或右)外连接.
随变量:第一年和第二年
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测试.