I want to improve this query, which I wrote for a small web application in ASP.NET 4.0, using SQL-Server 2005. This application will allow the user to search by product ID and return the following information:
- Highest purchase price + latest purchase date @ this price
- Lowest purchase price + latest purchase date @ this price
- Last purchase price + date
- Average purchase price (optional, I thought this could improve the utility of the application)
Here is the structure of the Products table (I include only the corresponding columns, this is an already created DB, and these are non-pk columns)
- product_id (nvarchar (20))
- price (decimal (19,2))
- pDate (datetime)
Before I put the request, I still want to say that I can easily get this information through several requests, so if this is best practice, ignore the improvement of the request, but I tried to minimize the number of requests needed to get all the necessary information.
What I still have: (Note: There are lines with price = 0, so I ignored those who select MIN price search at the bottom)
SELECT price, MAX(pDate) FROM Products WHERE product_id = @product_id AND (price = (SELECT MAX(price) FROM Products WHERE product_id =@product _id) OR price = (SELECT MIN(price) FROM Products WHERE product_id = @product_id AND price > 0)) GROUP BY price
Now this returns 2 rows:
- first = lowest price + date
- second row = high price + date
Ideally, I would like the query to return 1 row with all the necessary information mentioned above, if possible, as this would simplify the display of information in ASP for me. And, as I said earlier, if multiple queries are an approach, then there is no need to rewrite the complex query here.
Edit
Here are some sample data.

Desired query results: (ignore the format when I entered it in excel)

Here is a query that I will use thanks to Ken Benson:
SELECT TOP 1 prod.product_id, minp.price AS minprice, minp.pDate as minlastdate, maxp.price AS maxprice, maxp.pDate as maxlastdate, ag.price AS averageprice FROM products AS prod LEFT JOIN (SELECT lmd.product_id,max(lmd.pDate) as pDate,mn.price FROM products as lmd INNER JOIN (SELECT product_id, min(price) AS price from products WHERE price > 0 group by product_id) as mn ON lmd.product_id=mn.product_id AND lmd.price=mn.price group by lmd.product_id,mn.price ) AS minp ON minp.product_id=prod.product_id LEFT JOIN (SELECT lxd.product_id,max(lxd.pDate) as pDate,mx.price FROM products as lxd INNER JOIN (SELECT product_id, max(price) AS price from products group by product_id) as mx ON lxd.product_id=mx.product_id AND lxd.price=mx.price group by lxd.product_id,mx.price ) AS maxp ON maxp.product_id=prod.product_id LEFT JOIN (SELECT product_id,avg(price) as price FROM products WHERE price > 0 GROUP BY product_id) AS ag ON ag.product_id=prod.product_id WHERE prod.product_id=@product _id