代码之家  ›  专栏  ›  技术社区  ›  Jakub

SQL难题,如何为零件选择最新日期,但每个零件只能选择一行(唯一)

  •  5
  • Jakub  · 技术社区  · 14 年前

    今天早上我想把我的头绕在这个上面。

    我想表现出来 inventory

    我来安排一下:

    • 单张桌子 inventoryReport
    • 我有一个独特的列表,其中有X个零件我想显示,结果必须是X行(每一个零件1行显示最新的库存条目)。
    • 表是由库存变化的日期条目组成的(所以我只需要 LATEST 每个零件的日期输入)。
    • 所有数据都包含在这个表中,因此不需要联接。

    目前对于一个单独的部分来说,它相当简单,我可以通过执行以下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
    

    这就得到了我的第一行,每个部分都很简单,但是我需要显示所有的X(比如说30个部分)。所以我需要30行,这个结果。当然,简单的解决方案是在我的代码中循环X#个sql调用(但这会很昂贵),这就足够了,但是为了这个目的,我希望能对这个sql进行更多的处理,将X#个对db的调用(如果不需要的话)减少到只有一个查询。

    从这里我可以看到,我需要保持跟踪的最新日期,每项不知何故,同时寻找我的结果集。

    我最终会做一个

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

    限制我需要的零件。希望我的问题说得够清楚。如果你有主意就告诉我。我做不到 DISTINCT 因为行不同,所以日期必须是最新的,我最多需要X行。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Community CDub    8 年前

    编辑 this question CTE方法的性能可能优于使用行数的方法。

    ;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
    
        2
  •  5
  •   Michael Pakhantsov    14 年前
      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
    
        3
  •  2
  •   Leslie    14 年前

    您需要加入子查询:

    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