0

I have following tables
1) Products (productid, name, description, price)
2) Sales (salesid, productid, buyername, buyeremail, status)
3) ProductViews (viewid, productid)

Now, I need a query that can output as
     ProductID     ProductName     Price     TotalViews     TotalSales

Help appreciated, thanks.

1
  • is there a quantity in the sales table? or is it one row per sale? Commented Nov 24, 2010 at 13:12

4 Answers 4

1
SELECT p.productid, p.name, p.price, COUNT(pv.viewid) AS totalviews, COUNT(s.salesid) AS totalsales 
FROM Products p
LEFT JOIN Sales s ON s.productid = p.productid
LEFT JOIN ProductViews pv ON pv.productid = p.productid
GROUP BY p.productid, p.name, p.price

Extended group by for completeness sake but it could just be p.productid.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks, but is this query optimized or I have to do something to optimize it?
Assuming you have indexes on productid on each of the tables this is the most optimized query you can possibly have. Sub-selects are always nasty.
In this example all 3 tables should have an INDEX on productid. This will make the query/joins super fast even if they get large. Always INDEX your tables properly and use JOINs wherever you can.
1

You can use subqueries to get the count of views and sales:

SELECT 
    a.productid,
    a.name,
    a.price,
    (SELECT COUNT(b.viewid)
     FROM ProductViews b
     WHERE b.productid = a.productid) as TotalViews,
    (SELECT COUNT(c.salesid)
     FROM Sales c
     WHERE c.productid = a.productid) as TotalSales
FROM
    Products a

2 Comments

thanks, but is this query optimized or I have to do something to optimize it?
Gr8 answer. But this need little modification. See my answer for same
0
Select p.ProductID, p.ProductName, p.Price, s.c as TotalSales, v.c as TotalViews
FROM Products p
INNER JOIN (select productid, count(*) as c from Sales group by productid) s 
   ON s.productId = p.productid
INNER JOIN (select productid, count(*) as c from ProductViews group by productid) v 
   ON p.productId = v.productid

If you have a product that doesn't have a sale or a view you will need to left join instead

2 Comments

thanks, but is this query optimized or I have to do something to optimize it?
it's just one way to do it - use explain or similar and do some testing to find out.
0
SELECT a.productid, a.name, a.price, (

SELECT COUNT( b.viewid ) 
FROM ProductViews b
WHERE b.productid = a.productid
) AS TotalViews, (

SELECT COUNT( c.salesid ) 
FROM Sales c
WHERE c.productid = a.productid
) AS TotalSales

FROM products a 

3 Comments

If you have proper indexed tables sub-selects for rollups are never efficient.
what it means? I would to know more from you, can you elaborate it more @methodin
Any sub select requires the DB to create a temporary table, in memory, with no index. This of course is terribly slow. The proper way to handle queries such as this is to INDEX your tables on the columns being used on the join clause and use INNER/LEFT JOINs and a GROUP BY. See my answer for further elaboration. Add EXPLAIN before your query to see what the DB will do.

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.