我的应用程序有一个表,其中包含每年的快照库存数据。例如,车辆库存表中包含典型列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
(好的或坏的,这个表已经存在,它不是重新设计表的选项,这是另一个问题的主题)。你在这里看到的是年复一年,大多数车辆仍然在库存中,但总是有旧的车辆摆脱的情况,并且新的车辆被收购。在上面的例子中,1995年日产Altima在2009年的库存中,但不再是2010年的库存。 2010年的库存有一个新的2010福特Explorer。
如何构建一个有效查询,需要两年时间才能显示差异。例如,如果我在2009年,2010年通过,则查询应该返回
3 CCC777 1995 Nissan Altima white 2009
如果我在2010年,2009年通过,则查询应返回
6 DDD888 2010 Ford Explorer white 2010
编辑: 我应该在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
答案 0 :(得分: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
请注意,条件必须在连接条件内,以便数据库在没有匹配时返回空行,而不是找到稍后通过过滤删除的匹配。
修改:略微调整查询。这不需要子选择。用postgresql测试。
答案 1 :(得分:0)
select a.id, a.platenum, a.year, a.make, a.model, a.color, b.yearowned
from inventory a
join inventory b on a.platenum=b.platenum
where a.yearowned=___ and b.yearowned=___;
编辑:哎呀,我误解了。如何删除我的答案?
答案 2 :(得分:0)
此查询将选择2010年中表中不存在的所有汽车。
select *
from cars
where Year_Owned = 2010
and plate not in (
select plate
from cars
where year_owned < 2010);
使用这种结构,应该很明显如何重新排列它以生产2010年不再存在的汽车。
答案 3 :(得分:0)
我不确定这个想法会有多么'有效';但是你可以使用'EXCEPT'SQL语句。只是一个示例,这不会返回您想要的完整行,但是您会得到这个想法:
select plate, name from inventory where year_owned=2009
except
select plate, name from inventory where year_owned=2010
答案 4 :(得分:0)
我认为Kyle Butt给出了几乎完美的答案。他给了我90%的路。
以下是答案:
查询2010年的所有车辆,但不是2009年的库存:
select q.* from (
select f.* from inventory f
left join inventory s
on (f.plate_num = s.plate_num
and f.year_owned = 2010
and s.year_owned = 2009)
where s.plate_num is null
) q
where q.year_owned = 2010
查询2009年的所有车辆,但不是2010年的库存:
select q.* from (
select f.* from inventory f
left join inventory s
on (f.plate_num = s.plate_num
and f.year_owned = 2009
and s.year_owned = 2010)
where s.plate_num is null
) q
where q.year_owned = 2009