Desire correct row numbers using over PARTITION BY for invoices transaction in SQL Server

j5fpnvbx  于 2023-05-05  发布在  SQL Server
关注(0)|答案(1)|浏览(249)

I have a set of data containing invoice information. The goal is to find the credit and rebill invoice number ('InvcNbrKey') associated with a particular 'Standard Order' line. Think of it as a person orders an item which generate a line with 'OrdTypeName' = 'Standard Order', but later it was credited ('Rebill CM Req')and rebilled ('Rebill DM Req').

I attempted solving this problem by using Row_Number over Partition to isolate all transactions that share the same NDC, CustPO# and Location to put these transactions into the order which is described above: "Standard Order" followed by 'Rebill CM Req' then 'Rebill DM Req' so that I can eventually use Lead Function to return the correct Invoice Number for the credit

Select ROW_NUMBER() over (Partition by NDC,[CustPO#],[Location] Order by NDC,CustPO#,OrdNbrKey) as RowNumber
,*
From Invoices

Then this two lead functions to find the invoice and the date associated:

Case when (Lead([NetSales$],1) over (Partition by  NDC,[CustPO#],[Location] Order by NDC asc, CustPO#) = [NetSales$]*(-1))                
        
        Then concat('Credited with Invoice #',Lead([InvcNbrKey],1)  over (Partition by  NDC,[CustPO#],[Location] Order by [InvcDateKey]),' on '
            ,Lead([InvcDateKey],1)  over (Partition by  NDC,[CustPO#],[Location] Order by [InvcDateKey]) )  
        
        Else '' END as [HasThisBeenCredited]
    ,Case when (Lead([OrdTypeName],2) over (Partition by  NDC,[CustPO#],[Location] Order by NDC asc, CustPO#) = 'Rebill DM Req')

        Then concat('Rebilled with Invoice #',Lead([InvcNbrKey],2)  over (Partition by  NDC,[CustPO#],[Location] Order by [InvcDateKey]),' on '
            ,Lead([InvcDateKey],2)  over (Partition by  NDC,[CustPO#],[Location] Order by [InvcDateKey]) )  
        
        Else '' END as [HasThisBeenRebilled]

'''

It looks like this

But my desired return is this:

If my desired return is achieved, then I use lead function to return this information:

The problem is I cannot produce the desired return. I had great success using this approach if there are only three lines after the isolation using Partition by. However, when there are 6 lines. The problem is with putting the rows in the particular sequence described. Maybe this problem can be solved using an entire different approach rather than using row_number over partition by and lead function.

Any suggestion is appreciated.

Here is the sql for creating this table

INSERT INTO Invoices (InvoiceDate,OrdNbrKey,OrdTypeName,CustPO#,NDC,InvcNbrKey,InvoicePrice,HistoricWAC) VALUES ('1/25/2023','4608548197','Standard Order','MH01252023','50419039501','3121043683','7881.5','7881.5');
INSERT INTO Invoices (InvoiceDate,OrdNbrKey,OrdTypeName,CustPO#,NDC,InvcNbrKey,InvoicePrice,HistoricWAC) VALUES ('1/26/2023','4608548218','Standard Order','MH01252023','50419039501','3121044236','7881.5','7881.5');
INSERT INTO Invoices (InvoiceDate,OrdNbrKey,OrdTypeName,CustPO#,NDC,InvcNbrKey,InvoicePrice,HistoricWAC) VALUES ('4/13/2023','5148834452','Rebill CM Req','MH01252023','50419039501','352040045','7881.5','-7881.5');
INSERT INTO Invoices (InvoiceDate,OrdNbrKey,OrdTypeName,CustPO#,NDC,InvcNbrKey,InvoicePrice,HistoricWAC) VALUES ('4/13/2023','5148834454','Rebill DM Req','MH01252023','50419039501','352040046','8428.26','8428.26');
INSERT INTO Invoices (InvoiceDate,OrdNbrKey,OrdTypeName,CustPO#,NDC,InvcNbrKey,InvoicePrice,HistoricWAC) VALUES ('4/13/2023','5148837317','Rebill CM Req','MH01252023','50419039501','352043059','7881.5','-7881.5');
INSERT INTO Invoices (InvoiceDate,OrdNbrKey,OrdTypeName,CustPO#,NDC,InvcNbrKey,InvoicePrice,HistoricWAC) VALUES ('4/13/2023','5148837318','Rebill DM Req','MH01252023','50419039501','352043060','12866.4','12866.4');
cgyqldqp

cgyqldqp1#

You can try something like this:

SELECT * FROM
(
  SELECT
  ROW_NUMBER() over (Partition by a.NDC,a.[CustPO#], i1.[OrdNbrKey] ORDER BY i1.InvoiceDate, a.OrdNbrKey) as RowNumber,
  a.InvoiceDate,
  a.OrdNbrKey,
  a.InvcNbrKey,
  a.InvoicePrice,
  a.HistoricWAC,
  a.OrdTypeName,
  a.NDC,
  a.[CustPO#]
  FROM Invoices AS i1
  INNER JOIN (
    SELECT * FROM Invoices
  ) AS a ON i1.NDC = a.NDC AND i1.[CustPO#] = a.[CustPO#] AND (i1.[OrdNbrKey] = a.[OrdNbrKey] OR i1.[OrdTypeName] <> a.[OrdTypeName])
  WHERE i1.OrdTypeName = 'Standard Order'
) AS b WHERE b.RowNumber < 4

You can play a little with the conditions, to see all the data. This will most likely not produce the right data for you, as now the Credit and Debit is the same value for both orders. But as mentioned before, since they are not linked, it's not possible, to link the correct ones.

For the explanation of the query, you can see the self join here. If you would just select all columns from the inner select, you can see, i1.OrdNbrKey will produce our missing to partition by. The inner where condition will make sure, we get our own Standard Order but not the others, and the other types.

If you remove the most outer where condition, you will get a group of row numbers from 1 to 5, as it will produce one Standard Order and two Rebill CM and Rebill DM each. Hopefully this will help you.

i1 is our hidden table, just for grouping/partitioning/ordering

Result table:
| RowNumber | InvoiceDate | OrdNbrKey | InvcNbrKey | InvoicePrice | HistoricWAC | OrdTypeName | NDC | CustPO# |
| ------------ | ------------ | ------------ | ------------ | ------------ | ------------ | ------------ | ------------ | ------------ |
| 1 | 2023-01-25 | 4608548197 | 3121043683 | 7881.5 | 7881.5 | Standard Order | 50419039501 | MH01252023 |
| 2 | 2023-04-13 | 5148834452 | 352040045 | 7881.5 | -7881.5 | Rebill CM Req | 50419039501 | MH01252023 |
| 3 | 2023-04-13 | 5148834454 | 352040046 | 8428.26 | 8428.26 | Rebill DM Req | 50419039501 | MH01252023 |
| 1 | 2023-01-26 | 4608548218 | 3121044236 | 7881.5 | 7881.5 | Standard Order | 50419039501 | MH01252023 |
| 2 | 2023-04-13 | 5148834452 | 352040045 | 7881.5 | -7881.5 | Rebill CM Req | 50419039501 | MH01252023 |
| 3 | 2023-04-13 | 5148834454 | 352040046 | 8428.26 | 8428.26 | Rebill DM Req | 50419039501 | MH01252023 |

Without outer WHERE clause

RowNumberInvoiceDateOrdNbrKeyInvcNbrKeyInvoicePriceHistoricWACOrdTypeNameNDCCustPO#
12023-01-25460854819731210436837881.57881.5Standard Order50419039501MH01252023
22023-04-1351488344523520400457881.5-7881.5Rebill CM Req50419039501MH01252023
32023-04-1351488344543520400468428.268428.26Rebill DM Req50419039501MH01252023
42023-04-1351488373173520430597881.5-7881.5Rebill CM Req50419039501MH01252023
52023-04-13514883731835204306012866.412866.4Rebill DM Req50419039501MH01252023
12023-01-26460854821831210442367881.57881.5Standard Order50419039501MH01252023
22023-04-1351488344523520400457881.5-7881.5Rebill CM Req50419039501MH01252023
32023-04-1351488344543520400468428.268428.26Rebill DM Req50419039501MH01252023
42023-04-1351488373173520430597881.5-7881.5Rebill CM Req50419039501MH01252023
52023-04-13514883731835204306012866.412866.4Rebill DM Req50419039501MH01252023

相关问题