SAP Business One Last Prices Query

SQL queries to find the most recent price charged for a product to a specific customer, using invoice history.

INV1, OINV, OITM 4 min read

These are sample queries you can run on Manager Boost. Use them as-is, or edit and customize on our platform. Go custom or use our pre-built queries — you're in control.

Key Concepts

Last Price vs Price List

Price lists (ITM1, ITM2) show what you could charge. Invoice lines (INV1) show what you actually charged. The last price from invoices reflects real transactions, including discounts and special pricing.

Using ROW_NUMBER()

To get the most recent price, use ROW_NUMBER() partitioned by customer and item, ordered by invoice date descending. Filter ROW_NUMBER() = 1 to get only the latest transaction.

Joining via DocEntry

INV1 links to OINV via DocEntry (the primary key). Always use DocEntry for joins — it's indexed and guaranteed unique. Use OINV to get invoice date and customer code.

Price Field on INV1

Price on INV1 is the unit price after line-level discounts. This is the actual price charged per unit. LineTotal is the total for that line (Price × Quantity).

Filtering Cancelled Invoices

Always join OINV and filter CANCELED = 'N' to exclude cancelled invoices. Cancelled invoices stay in the database but shouldn't be used for price history.

Available Fields Reference

INV1 (Invoice Lines)

DocEntry LineNum ItemCode Dscription Quantity Price LineTotal DiscPrcnt

OINV (Invoice Header)

DocEntry DocNum DocDate CardCode CardName CANCELED

OITM (Item Master)

ItemCode ItemName ItmsGrpCod

Last Price of Product to Customer

Get the most recent price charged for a specific product to a specific customer. Uses ROW_NUMBER() to identify the latest invoice line.

SQLMS SQL Server
SELECT 
    T1.ItemCode,
    T2.ItemName,
    T0.CardCode,
    T0.CardName,
    T1.Price AS LastPrice,
    T1.Quantity,
    T0.DocDate AS LastInvoiceDate,
    T0.DocNum AS LastInvoiceNum
FROM OINV T0
INNER JOIN INV1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN OITM T2 ON T1.ItemCode = T2.ItemCode
WHERE T0.CardCode = 'C10000'
  AND T1.ItemCode = 'A00001'
  AND T0.CANCELED = 'N'
  AND (
    SELECT ROW_NUMBER() OVER (
        PARTITION BY T1.ItemCode, T0.CardCode 
        ORDER BY T0.DocDate DESC, T0.DocEntry DESC
    )
  ) = 1

Note: The above query uses a subquery for ROW_NUMBER which may not work in all SQL Server versions. Use the CTE version below for better compatibility.

SQLMS SQL Server
WITH RankedPrices AS (
    SELECT 
        T0.CardCode,
        T0.CardName,
        T1.ItemCode,
        T2.ItemName,
        T1.Price,
        T1.Quantity,
        T0.DocDate,
        T0.DocNum,
        ROW_NUMBER() OVER (
            PARTITION BY T1.ItemCode, T0.CardCode 
            ORDER BY T0.DocDate DESC, T0.DocEntry DESC
        ) AS RowNum
    FROM OINV T0
    INNER JOIN INV1 T1 ON T0.DocEntry = T1.DocEntry
    INNER JOIN OITM T2 ON T1.ItemCode = T2.ItemCode
    WHERE T0.CANCELED = 'N'
)
SELECT 
    CardCode,
    CardName,
    ItemCode,
    ItemName,
    Price AS LastPrice,
    Quantity,
    DocDate AS LastInvoiceDate,
    DocNum AS LastInvoiceNum
FROM RankedPrices
WHERE CardCode = 'C10000'
  AND ItemCode = 'A00001'
  AND RowNum = 1
Sample Result
CardCodeCardNameItemCodeItemNameLastPriceLastInvoiceDateLastInvoiceNum
C10000Acme CorpA00001Widget Pro450.002024-01-1512345

All Last Prices for a Customer

Get the most recent price for every product ever sold to a customer. Useful for pricing analysis and customer-specific price lists.

SQLMS SQL Server
WITH RankedPrices AS (
    SELECT 
        T0.CardCode,
        T0.CardName,
        T1.ItemCode,
        T2.ItemName,
        T1.Price,
        T1.Quantity,
        T0.DocDate,
        T0.DocNum,
        ROW_NUMBER() OVER (
            PARTITION BY T1.ItemCode, T0.CardCode 
            ORDER BY T0.DocDate DESC, T0.DocEntry DESC
        ) AS RowNum
    FROM OINV T0
    INNER JOIN INV1 T1 ON T0.DocEntry = T1.DocEntry
    INNER JOIN OITM T2 ON T1.ItemCode = T2.ItemCode
    WHERE T0.CardCode = 'C10000'
      AND T0.CANCELED = 'N'
)
SELECT 
    ItemCode,
    ItemName,
    Price AS LastPrice,
    Quantity AS LastQuantity,
    DocDate AS LastInvoiceDate,
    DocNum AS LastInvoiceNum
FROM RankedPrices
WHERE RowNum = 1
ORDER BY ItemCode
Sample Result
ItemCodeItemNameLastPriceLastQuantityLastInvoiceDate
A00001Widget Pro450.00102024-01-15
A00002Gadget Plus275.0052024-01-10

Price History Over Time

Track how prices changed for a product-customer combination. Shows all historical prices, not just the latest.

SQLMS SQL Server
SELECT 
    T0.DocDate,
    T0.DocNum,
    T0.CardCode,
    T0.CardName,
    T1.ItemCode,
    T2.ItemName,
    T1.Price,
    T1.Quantity,
    T1.LineTotal
FROM OINV T0
INNER JOIN INV1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN OITM T2 ON T1.ItemCode = T2.ItemCode
WHERE T0.CardCode = 'C10000'
  AND T1.ItemCode = 'A00001'
  AND T0.CANCELED = 'N'
ORDER BY T0.DocDate DESC, T0.DocEntry DESC
Sample Result
DocDateDocNumPriceQuantityLineTotal
2024-01-1512345450.00104500.00
2023-12-1012200425.0083400.00
2023-11-0512050400.00124800.00

Tip: This shows all prices chronologically. To see only price changes, add logic to compare each row to the previous row's price.

Give your team answers in 3 seconds

No SQL. No training. Just plain English questions via SMS.