0

I have a SELECT statement that pulls in product information from a related table, and finds the product with the highest quantity associated to it for that transaction. This is shown below and working as expected:

SELECT qty.[Id], qty.[Product_Name], qty.[Product_Type] FROM ( SELECT td.[Id], prd.[Product_Name], prd.[Product_Type], ROW_NUMBER() OVER (PARTITION BY prd.Receipt_Number ORDER BY prd.Quantity DESC) AS Row FROM [Transactions] td INNER JOIN [Products] prd ON prd.[Receipt_Number] = td.[Receipt_Number] WHERE prd.Quantity > 1 ) qty WHERE qty.Row = 1 

The issue is that there may be multiple products that have the exact same quantity. Current the system will pull in the first record it finds of the multiple matches, but I would like to exclude this inner query entirely if there is a tie on the highest quantity, returning a null value. Is this possible?

1
  • Unclear... Assume you have 2 transactions (Receipt_Number), 1 product (P1) with the highest quantity associated with 1st transaction and 2 products (P2, P3) with the same highest quantity associated with 2nd transaction. Your query will return 2 records: P1 and one random from (P2,P3). Where do you want a NULL value to be returned? And the same when the products are P1 and (P1, P2) respectively. Commented Feb 28, 2019 at 5:09

2 Answers 2

1

It's a bit unclear what you want, but you can use rank() to collect duplicates, and then another window function that counts those, and filter them out if there is more than one:

SELECT qty.Id , qty.Product_Name , qty.Product_Type FROM ( SELECT qty.Id , qty.Product_Name , qty.Product_Type , COUNT(Rnk) OVER () as cnt FROM ( SELECT td.Id, prd.Product_Name, prd.Product_Type , RANK() OVER (PARTITION BY prd.Receipt_Number ORDER BY prd.Quantity) AS Rnk FROM Transactions td JOIN Products prd ON prd.Receipt_Number = td.Receipt_Number WHERE prd.Quantity > 1 ) qty WHERE qty.Rnk = 1 ) WHERE cnt = 1; 

If you want the rows, but with null instead of values you can use a case expression:

SELECT CASE WHEN cnt = 1 THEN qty.Id END , CASE WHEN ... qty.Product_Name ... , ... FROM ( ... ); 
3
  • With COUNT(*) OVER (PARTITION BY Receipt_number, Quanity) , you could have only 1 CTE. Commented Feb 28, 2019 at 12:04
  • 1
    I have 0 now, but I see your point ;-) I'm not entirely sure what the OP wants, so I more or less just copied the original query and adapted it. Commented Feb 28, 2019 at 12:24
  • I meant 1 level of CTEs or derived table, instead of 2 levels. Commented Feb 28, 2019 at 12:33
0
with qty as ( SELECT td.[Id], prd.[Product_Name], prd.[Product_Type], rank() OVER (PARTITION BY prd.Receipt_Number ORDER BY prd.Quantity DESC) AS rnk FROM [Transactions] td INNER JOIN [Products] prd ON prd.[Receipt_Number] = td.[Receipt_Number] WHERE prd.Quantity > 1 ) ,cte1 as ( select * from qty where rnk = 1 ) SELECT [Id], case when max(Product_Name) = min(Product_Name) then max(Product_Name) end as Product_Name, case when max(Product_Name) = min(Product_Name) then max(Product_Type) end as Product_Type FROM cte1 group by Receipt_Number; 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.