Nicolas.
Nicolas.

Reputation: 453

How to count rows from a different table during same SQL query

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

Answers (2)

ScaisEdge
ScaisEdge

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

spencer7593
spencer7593

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

Related Questions