Sql查询选择每个不同的最后一行以及使用内部联接检索的其他列

时间:2015-05-08 21:45:59

标签: sql sql-server

我从sql语言开始,所以我会尽力指出我的问题。我一直在阅读其他问题,但似乎没有人适合我。所以......

我需要从InventoryEntriesDetail表中找到每个供应商的每个项目的最后付款价格。

由于表InventoryEntriesDetail包含销售和采购文档,我已将InventoryEntriesDetail表加入InventoryEntries表并对其进行过滤以仅获取采购文档。

现在我有几行:supplier,item,date,docNr等。但我只需要每个供应商/项目的最后一条记录。

有什么建议吗?

根据要求,这是我到目前为止的地方

SELECT 
    dbo.MA_InventoryEntries.CustSupp as Supplier, 
    dbo.MA_InventoryEntriesDetail.Item as Item, 
    dbo.MA_InventoryEntriesDetail.PostingDate as Date,
    dbo.MA_InventoryEntries.InvRsn AS InvRsn, 
    dbo.MA_InventoryEntriesDetail.Qty as Qty, 
    dbo.MA_InventoryEntriesDetail.UnitValue as Price, 
    dbo.MA_InventoryEntriesDetail.DiscountFormula as Discount, 
    dbo.MA_InventoryEntriesDetail.EntryId as ID
FROM 
    dbo.MA_InventoryEntriesDetail 
    LEFT OUTER JOIN dbo.MA_InventoryEntries 
        ON dbo.MA_InventoryEntriesDetail.EntryId = dbo.MA_InventoryEntries.EntryId
WHERE 
    dbo.MA_InventoryEntries.CustSuppType = 6094849
ORDER BY 
    Supplier, 
    Item, 
    Date

一些注意事项:

  • 最后一个EntryId并不总是我正在搜索的记录

  • 左连接是一个必须'因为几年前仅使用InvRsn完成了InventoryEntriesDetail(它总是在InventoryEntries(非详细信息)中)

  • 我使用的数据库在2001年有它的第一个记录,所以我们加入的表有超过11毫升的记录

PS:感谢Chris Albert纠正这个问题。现在它更清楚了。 :)

1 个答案:

答案 0 :(得分:0)

您可以使用ROW_NUMBER()标识每个supplier, item分区的最后一条记录:

SELECT supplier, item, date, docNr, qty, price, DiscountFormula
FROM (
   SELECT supplier, item, date, docNr, qty, price, DiscountFormula
          ROW_NUMBER() OVER (PARTITION BY supplier, item 
                             ORDER BY date DESC) AS rn
   FROM yourtable )
WHERE t.rn = 1

如果您有多个“最后”记录并且您想要选择所有记录,则可以使用RANK()代替ROW_NUMBER()

修改

这是猜测您的实际查询应该如何(在OP中进行编辑之后):

SELECT Supplier, Item, Date, InvRsn, Qty, Price, Discount, ID
FROM (
    SELECT 
        dbo.MA_InventoryEntries.CustSupp as Supplier, 
        dbo.MA_InventoryEntriesDetail.Item as Item, 
        dbo.MA_InventoryEntriesDetail.PostingDate as Date,
        dbo.MA_InventoryEntries.InvRsn AS InvRsn, 
        dbo.MA_InventoryEntriesDetail.Qty as Qty, 
        dbo.MA_InventoryEntriesDetail.UnitValue as Price, 
        dbo.MA_InventoryEntriesDetail.DiscountFormula as Discount, 
        dbo.MA_InventoryEntriesDetail.EntryId as ID,
        RANK() OVER (PARTITION BY dbo.MA_InventoryEntries.CustSupp, 
                                  dbo.MA_InventoryEntriesDetail.Item
                     ORDER BY dbo.MA_InventoryEntriesDetail.PostingDate DESC) AS rn
    FROM 
        dbo.MA_InventoryEntriesDetail 
        LEFT OUTER JOIN dbo.MA_InventoryEntries 
            ON dbo.MA_InventoryEntriesDetail.EntryId = dbo.MA_InventoryEntries.EntryId
    WHERE 
        dbo.MA_InventoryEntries.CustSuppType = 6094849 ) t
WHERE t.rn = 1
ORDER BY Supplier, Item, Date