Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get a count of associated rows in a left join in MySQL?

Tags:

I have two tables, a vehicle table with columns:

  • id
  • stock
  • year
  • make
  • model

and an images table with columns:

  • id
  • vehicle_id
  • name
  • caption
  • default tinyint(1)

I am trying to list the vehicle's information, its default image, and a total count of images the vehicle has. Currently I am using the following SELECT statement:

SELECT vehicle.id, vehicle.stock, vehicle.year,
    vehicle.make, vehicle.model, images.name,
    COUNT(images.id)
FROM vehicle
LEFT JOIN images
ON vehicle.id = images.vehicle_id

I initially was using:

ON vehicle.id = images.vehicle_id AND images.default = 1

but then the images count would only be 1 or 0 depending if there was a default image in the database. I have tried using UNION and other SELECT statements but I am still unable to get a proper result. Do I need to use two SELECT statements or is there another way to handle it with JOIN or UNION?

like image 641
Cris McLaughlin Avatar asked Apr 30 '09 18:04

Cris McLaughlin


People also ask

How do I count the number of rows in a SQL join?

Use the COUNT aggregate function to count the number of rows in a table. This function takes the name of the column as its argument (e.g., id ) and returns the number of rows for this particular column in the table (e.g., 5).

How many rows will return for left join?

The SQL LEFT JOIN returns all rows from the left table, even if there are no matches in the right table. This means that if the ON clause matches 0 (zero) records in the right table; the join will still return a row in the result, but with NULL in each column from the right table.

How do I count specific rows in MySQL?

To counts all of the rows in a table, whether they contain NULL values or not, use COUNT(*). That form of the COUNT() function basically returns the number of rows in a result set returned by a SELECT statement.

How can LEFT join increase row count?

It's using an aggregate function (COUNT), but no GROUP BY clause, so it should produce exactly 1 row, no matter what is in the tables. Perhaps you meant to say that it produces 1 row, and the count on that row is 1176. You're counting all values, not distinct values, like you're doing in the 2nd query.


2 Answers

SELECT 
    `vehicle`.`id`, 
    `vehicle`.`stock`, 
    `vehicle`.`year`, 
    `vehicle`.`make`, 
    `vehicle`.`model`, 
    `images`.`name`,
    (
        SELECT COUNT(*) 
        FROM `images` 
        WHERE `vehicle_id` = `vehicle`.`id`
    ) AS `image_count`
FROM `vehicle`
LEFT JOIN `images`
ON `images`.`vehicle_id` = `vehicle`.`id`
WHERE `images`.`default`
like image 63
chaos Avatar answered Sep 17 '22 03:09

chaos


In the way the anser suggests, you get repeated values of "vehicle". A better way, is to group results. Try without the JOIN :

SELECT 
    `vehicle`.`id`, 
    `vehicle`.`stock`, 
    `vehicle`.`year`, 
    `vehicle`.`make`, 
    `vehicle`.`model`, 
    `images`.`name`,
    (
        SELECT COUNT(*) 
        FROM `images` 
        WHERE `vehicle_id` = `vehicle`.`id`
    ) AS `image_count`
FROM `vehicle`

WHERE `images`.`default`
like image 28
gdm Avatar answered Sep 18 '22 03:09

gdm