Reputation: 453
I would like to get all the jobs for a person, and count all the bids he received which is stored in a different table.
I have one table with following rows:
table jobs: jobId,userid,title
And a different table with the following:
table bids: jobId,amount
Now I want to get all the jobs from the first table jobs WHERE userid=1
and combine this with counting all rows in the second table table bids
that have the same jobId
for each job (line) that is found from the first table.
A possible output could be:
job.jobId job.userid job.title bids.Total
1 10 "My job" 20
2 11 "Other job" 5
I know how to do it the wrong way, which is like this:
$stmt0 = $mysqli->stmt_init();
$stmt0->prepare("SELECT jobId,title FROM jobs WHERE userid=?");
$stmt0->bind_param('i', $userid);
$stmt0->execute();
$stmt0->bind_result($jobId,$title);
// Fetch the result of the query
while($stmt0->fetch()) {
$ary = "SELECT amount FROM bids WHERE jobId='$jobId'";
if ($stmt_1 = mysqli_prepare($mysqli, $ary)) {
mysqli_stmt_execute($stmt_1);
mysqli_stmt_store_result($stmt_1);
$total_bids = mysqli_stmt_num_rows($stmt_1);
mysqli_stmt_close($stmt_1);
}
// show all jobs with total bids
...
}
$stmt0->close();
How can I do this with one query?
Upvotes: 2
Views: 119
Reputation: 133360
You could use a Join a count and group by
SELECT a.jobId,a.userid, a.title, count(b.jobid) as bidsTotal
FROM jobs as a
inner join bids as b on b.jobId = a.JobId
WHERE userid=?
Group by a.jobId,a.userid, a.title
Upvotes: 1
Reputation: 108370
You could emulate the current "wrong way" approach in a single query, using correlated subquery in the SELECT list, so you would have just one query:
SELECT j.jobId
, j.title
, j.userid
, ( SELECT COUNT(*)
FROM bids b
WHERE b.jobId = j.jobId
) AS cnt_bids
FROM jobs j
WHERE j.userid = ?
ORDER BY j.jobId
The correlated subquery will get executed for every row returned by the outer query. This approach gets expensive if the outer query returns a large number of rows.
If there is a column (or set of columns) that are UNIQUE in the jobs
table, we can get an equivalent result using an OUTER JOIN operation and a GROUP BY.
If we have a guarantee that jobId
is UNIQUE in the jobs
table, an equivalent result can be obtained using an outer join operation
SELECT j.jobId
, j.title
, j.userid
, COUNT(b.jobId) AS cnt_bids
FROM jobs j
LEFT
JOIN bids b
ON b.jobId = j.jobId
WHERE j.userid = ?
GROUP BY j.jobId, j.title, j.userid
ORDER BY j.jobId
Upvotes: 1