How to query Products by Opportunity?

You can use OpportunityLineItem to traverse from Opportunity to PricebookEntry and Product..

something like this query

SELECT Id, Name, Account.Name, 
  (SELECT Quantity, UnitPrice, TotalPrice, 
   PricebookEntry.Name, PricebookEntry.Product2.Family FROM 
   OpportunityLineItems) 
FROM Opportunity WHERE Id = :YourOppId

You can also refer this object model to understand the relationship between Product, Pricebook, OpportunityLineItem and Opportunity objects


Try this

select id, quantity, unitPrice, totalPrice, productCode, product2.someFldOnProduct2, 
       opportunity.name, opportunity.amount, opportunity.somefieldOnOppo
    from OpportunityLineItem 
    where opportunity.stageName = 'Closed'

You need to be at Version 30 or higher to do this as the lookup relationship from OpportunityLineItem to Product2 didn't exist until then.

Grouping / aggregating omitted from the above, exercise left to the reader; you could also do summarization/grouping in Apex