2010-09-09 32 views
5

今天早上我正试图围绕这一个问题进行讨论。SQL难题,如何选择部分的最新日期,但每个部分只有1行(独特)

我试图显示inventory部件(对于我们的产品)的状态,如果我尝试返回所有部件,此查询将变得复杂。

让我摊开来:

  • 单个表inventoryReport
  • 我的X部分明显的名单我想显示其结果必须是行X#(每部分1行显示最新的库存条目)。
  • 表由库存变更的日期条目组成(所以我只需要每个零件的LATEST日期条目)。
  • 所有数据都包含在这张表中,所以不需要加入。

目前为1周单的一部分,它是相当简单的,我可以做如下的sql完成这个(给你一些想法):

SELECT  TOP (1) ldDate, ptProdLine, inPart, inSite, inAbc, ptUm, inQtyOh + inQtyNonet AS in_qty_oh, inQtyAvail, inQtyNonet, ldCustConsignQty, inSuppConsignQty 
FROM   inventoryReport 
WHERE  (ldPart = 'ABC123') 
ORDER BY ldDate DESC 

这让我我的TOP 1列,所以每部分简单,但我需要显示所有的X(可以说30个部分)。所以我需要30行,结果。当然,简单的解决方案是在我的代码中循环使用X#的SQL调用(但是代价很高),这样就足够了,但为了这个目的,我希望能够更多地使用这个SQL来将x#调用回到db (如果不需要)只需要1个查询。

从我能看到的这里我需要跟踪每个项目的最新日期,同时寻找我的结果集。

我最终会做一个

WHERE ldPart in ('ABC123', 'BFD21', 'AA123', etc) 

限制我需要的部分。我希望我的问题足够清楚。让我知道你是否有想法。由于行不一样,我不能做DISTINCT,日期需要是最新的,我需要最多X行。

想法?我卡住了...

回答

2

编辑:一定要测试每个解决方案的性能。正如在this question中指出的那样,CTE方法可能会使用ROW_NUMBER。

;with cteMaxDate as (
    select ldPart, max(ldDate) as MaxDate 
     from inventoryReport 
     group by ldPart 
) 
SELECT md.MaxDate, ir.ptProdLine, ir.inPart, ir.inSite, ir.inAbc, ir.ptUm, ir.inQtyOh + ir.inQtyNonet AS in_qty_oh, ir.inQtyAvail, ir.inQtyNonet, ir.ldCustConsignQty, ir.inSuppConsignQty 
    FROM cteMaxDate md 
     INNER JOIN inventoryReport ir 
      on md.ldPart = ir.ldPart 
       and md.MaxDate = ir.ldDate 
5
SELECT * 
    FROM (SELECT i.*, 
     ROW_NUMBER() OVER(PARTITION BY ldPart ORDER BY ldDate DESC) r 
     FROM inventoryReport i 
     WHERE ldPart in ('ABC123', 'BFD21', 'AA123', etc) 
     ) 
    WHERE r = 1 
2

你需要加入到一个子查询:

SELECT i.ldPart, x.LastDate, i.inAbc 
FROM inventoryReport i 
INNER JOIN (Select ldPart, Max(ldDate) As LastDate FROM inventoryReport GROUP BY ldPart) x 
on i.ldPart = x.ldPart and i.ldDate = x.LastDate