SQL在没有子查询的情况下获取最新结果

时间:2015-10-22 05:49:52

标签: sql sql-server

我正在使用以下查询获取某些商品信息:

select inventory.itemnum, item.description, invcost.avgcost, invtrans.physcnt
from inventory
    join item on inventory.itemnum = item.itemnum
    join invcost on inventory.itemnum = invcost.itemnum
    join invtrans on inventory.itemnum = invtrans.itemnum
where inventory.location = 'A'
    and invcost.location = 'A' and invtrans.transdate like '%2015%'
    and invtrans.transtype = 'PCOUNTADJ'
    and invtrans.storeloc = 'A';

查询当前仅返回每个项目的一条记录,并且它使用基于当前年份(例如2015年)的INVTRANS表中的第一条记录。当那个年份有多个类型为“PCOUNTADJ”的INVTRANS记录时,这就成了一个问题。

如何才能使用最新的(max(transdate))?

我知道我可以像这样使用子查询:

...invtrans.transdate = (select max(transdate) from INVTRANS where...)

但是我必须重复与INVENTORY的连接,我已经失去了对外部查询的itemnum的引用

1 个答案:

答案 0 :(得分:3)

您可以使用CROSS APPLY

select inventory.itemnum, item.description, invcost.avgcost, i.physcnt
from inventory 
join item on inventory.itemnum = item.itemnum 
join invcost on inventory.itemnum = invcost.itemnum 
cross apply (
   select top 1 physcnt
   from invtrans
   where inventory.itemnum = invtrans.itemnum and 
         invtrans.transdate like '%2015%' and
         invtrans.transtype = 'PCOUNTADJ' and 
         invtrans.storeloc = 'A'
   order by transdate desc) AS i(physcnt)    
where inventory.location = 'A' and invcost.location = 'A';

如果在INVTRANS年内有多个'PCOUNTADJ'类型为2015的{​​{1}}条记录,则CROSS APPLY会返回具有最新转化的记录。

另一种方法涉及窗口函数:

select itemnum, description, avgcost, physcnt
from (
  select inventory.itemnum, item.description, 
         invcost.avgcost, invtrans.physcnt,
         row_number() over (partition by invtrans.itemnum 
                            order by invtrans.transdate desc) as rn
  from inventory 
  join item on inventory.itemnum = item.itemnum 
  join invcost on inventory.itemnum = invcost.itemnum 
  join invtrans on inventory.itemnum = invtrans.itemnum
  where inventory.location = 'A' and invcost.location = 'A' and 
        invtrans.transdate like '%2015%' and 
        invtrans.transtype = 'PCOUNTADJ' and 
        invtrans.storeloc = 'A' ) as t
where t.rn = 1 
上述查询中的

ROW_NUMBER会根据1最新行返回itemnum