1

I have been trying to find a similar case. I found a lot, but I still can't figure it out to adopt to my query.

I have a testDB in SQL Server that has 3 tables, as shown in picture below:

Table Structure

I created query as below:

SELECT P.FirstName,
        P.LastName,
        O.ProductType, 
        PO.ProductName,
        PO.Quantity 
FROM Persons AS P
INNER JOIN Orders AS O ON P.PersonID = O.PersonID 
INNER JOIN ProductOrders AS PO ON PO.OrderID = O.OrderID;

Current result, it shows all records from ProductOrders. See picture below:

Current Result

I want the result that only shows, for each Person name only record with the highest quantity. My expected result as shown in picture below:

Expected Result

Thanks very much for your help.

4
  • What if someone had 2 iPhone's and 2 Samsungs? Commented Mar 9, 2018 at 15:24
  • use group by in query Commented Mar 9, 2018 at 15:24
  • Your first picture is wrong. The persons table doesn't have a productid. The order table doesn't either, so no foreign key on that of course. The product order table doesnt have a foreign key on product and order, but two foreign keys one for each column. Better delete that image; it's not helpful. And as to images in general: Please don't use them if not absolutely needed to show your issue. Paste the tables as text instead, so we can copy & paste, can even see them even when we can't see pictures, etc. Commented Mar 9, 2018 at 16:01
  • Your description is also wrong: "I want the result only shows, for each Person name only record with the highest Quantity." Obviously you don't want the product with the highest quantity per person, but per person and product type (otherwise each name would appear only once in your results). Commented Mar 9, 2018 at 16:10

2 Answers 2

3

SQL Server has the TOP WITH TIES/ROW_NUMBER() trick that does this very elegantly:

SELECT TOP (1) WITH TIES P.FirstName, P.LastName, O.ProductType, PO.ProductName, PO.Quantity 
FROM Persons P INNER JOIN
     Orders O
     ON P.PersonID = O.PersonID INNER JOIN
     ProductOrders PO
     ON PO.OrderID = O.OrderID
ORDER BY ROW_NUMBER() OVER (PARTITION BY P.PersonId, P.ProductType ORDER BY PO.Quantity DESC);
Sign up to request clarification or add additional context in comments.

5 Comments

That should be (PARTITION BY P.PersonId, O.ProductType ORDER BY PO.Quantity DESC).
Thanks Gordon. I try your query, but I got an error "Incorrect syntax near the keyword 'DESC'." Not sure what is incorrect.
Updated: Follow @ThorstenKettner comment will solve my the "Incorrect syntax near the keyword 'DESC'." error. Thanks very much everyone.
@Gordon, if I want to final result to Sort by P.FirstName, is it possible? Thanks
@Harzio . . . If you wanted to do that, you would need a subquery or CTE.
0

Use Window functions:

SELECT distinct P.FirstName
            , P.LastName
            , O.ProductType
            , first_value(O.ProductName) OVER (Partition By P.FirstName, P.LastName, O.ProductType Order by PO.Quantity desc) as [Productname]
            , max(PO.Quantity) OVER (Partition By P.FirstName, P.LastName, O.ProductType) as [Quantity]
FROM Persons AS P 
INNER JOIN Orders AS O ON P.PersonID = O.PersonID 
INNER JOIN ProductOrders AS PO ON PO.OrderID = O.OrderID;

1 Comment

Thanks very much, @cloudsafe. I run your query and it does what I want.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.