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

发布于 2024-09-18 00:58:03 字数 1046 浏览 0 评论 0原文

今天早上我正在努力解决这个问题。

我试图显示零件(对于我们的产品)的库存状态,并且如果我尝试返回所有零件,此查询只会变得复杂。

让我列出来:

  • 单表 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

这让我获得了我的前 1 行,每个部分都很简单,但是我需要显示所有 X(让说 30 部分)。所以我需要 30 行才能得到这个结果。当然,简单的解决方案是在我的代码中循环 X# 的 sql 调用(但这会很昂贵),这就足够了,但为了这个目的,我很乐意进一步处理这个 SQL,以减少对数据库的 x# 调用(如果不需要)减少到只有 1 个查询。

从我在这里可以看到,我需要在查找结果集时以某种方式跟踪每个项目的最新日期。

我最终会做一个

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

来限制我需要的部分。希望我的问题足够清楚。如果您有想法,请告诉我。我无法执行 DISTINCT,因为行不相同,日期需要是最新的,并且我最多需要 X 行。

想法?我被困住了...

I am trying to wrap my head around this one this morning.

I am trying to show inventory status for parts (for our products) and this query only becomes complex if I try to return all parts.

Let me lay it out:

  • single table inventoryReport
  • I have a distinct list of X parts I wish to display, the result of which must be X # of rows (1 row per part showing latest inventory entry).
  • table is made up of dated entries of inventory changes (so I only need the LATEST date entry per part).
  • all data contained in this single table, so no joins necessary.

Currently for 1 single part, it is fairly simple and I can accomplish this by doing the following sql (to give you some idea):

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

that gets me my TOP 1 row, so simple per part, however I need to show all X (lets say 30 parts). So I need 30 rows, with that result. Of course the simple solution would be to loop X# of sql calls in my code (but it would be costly) and that would suffice, but for this purpose I would love to work this SQL some more to reduce the x# calls back to the db (if not needed) down to just 1 query.

From what I can see here I need to keep track of the latest date per item somehow while looking for my result set.

I would ultimately do a

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

to limit the parts I need. Hopefully I made my question clear enough. Let me know if you have an idea. I cannot do a DISTINCT as the rows are not the same, the date needs to be the latest, and I need a maximum of X rows.

Thoughts? I'm stuck...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝海似她心 2024-09-25 00:58:03
  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
  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
别理我 2024-09-25 00:58:03

编辑:请务必测试每个解决方案的性能。正如这个问题,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

EDIT: Be sure to test the performance of each solution. As pointed out in this question, the CTE method may outperform using 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
趴在窗边数星星i 2024-09-25 00:58:03

您需要加入子查询:

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

You need to join into a Sub-query:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文