I couldn't be more specific in the title part but I want to do something a little bit complex for me. I thought I did it but it turned out that it is buggy.
I have three tables as following:
ProjectTable
OfferTable
- idOffer
- idProject
- idAccount
AccountTable
Now in one query I aim to list all the projects with most offers made, and in the query I also want to get details like the username of the owner, username of the offerer* etc. So I don't have to query again for each project.
Here is my broken query, it's my first experiment with GROUP BY and I probably didn't quite get it.
SELECT Project.addDate,Project.idOwner ,Account.Username,Project.idProject,
Project.Price,COUNT(Project.idProject) as offercount
FROM Project
INNER JOIN Offer
ON Project.idProject= Offer.idProject
INNER JOIN Account
ON Account.idAccount = Project.idOwner
GROUP BY Project.addDate,Project.idOwner,
Account.Username,Project.idProject,Project.Price
ORDER BY addDate DESC
*:I wrote that without thinking I was just trying to come up with example extra information, that is meaningless thanks to Hosam Aly.
Try this (modified for projects with no offers):
SELECT
Project.addDate,
Project.idOwner,
Account.Username,
Project.idProject,
Project.Price,
ISNULL(q.offercount, 0) AS offercount
FROM
(
SELECT
o.idProject,
COUNT(o.idProject) as offercount
FROM Offer o
GROUP BY o.idProject
) AS q
RIGHT JOIN Project ON Project.idProject = q.idProject
INNER JOIN Account ON Account.idAccount = Project.idOwner
ORDER BY addDate DESC
I might switch the query slightly to this:
select p.addDate,
p.idOwner,
a.Username,
p.idProject,
p.price,
o.OfferCount
from project p
left join
(
select count(*) OfferCount, idproject
from offer
group by idproject
) o
on p.idproject = o.idproject
left join account a
on p.idowner = a.idaccount
This way, you are getting the count
by the projectid
and not based on all of the other fields you are grouping by. I am also using a LEFT JOIN
in the event the projectid
or other id doesn't exist in the other tables, you will still return data.
Your question is a bit vague, but here are some pointers:
- To list the projects "with most offers made",
ORDER BY offercount
.
- You're essentially querying for projects, so you should
GROUP BY Project.idProject
first before the other fields.
- You're querying for the number of offers made on each project, yet you ask about offer details. It doesn't really make sense (syntax-wise) to ask for the two pieces of information together. If you want to get the total number of offers, repeated in every record of the result, along with offer information, you'll have to use an inner query for that.
An inner query can be made either in the FROM
clause, as suggested by other answers, or directly in the SELECT
clause, like so:
SELECT Project.idProject,
(SELECT COUNT(Offer.idOffer)
FROM Offer
WHERE Offer.idProject = Project.idProject
) AS OfferCount
FROM Project