wordman
wordman

Reputation: 581

How to count rows from multiple tables using one query

My DB contains information about specific projects. Each project is made of multiple parts, and each part has one or more photo galleries. I want to know if I can count the number of project parts, galleries and photos associated with any given project using only one query. Currently there is 1 project in the system that has 3 parts, 5 galleries and 302 photos.

This query (with thanks to many here from SO) works fine to count the number of parts per project, which currently is 3:

// count number of parts per project
$conn = dbConnect('query');
$galNumb = "SELECT COUNT(*) FROM pj_parts WHERE pj_id = ?";
$stmt = $conn->prepare($galNumb);
$stmt->bind_param('i', $project);
$stmt->bind_result($galTotal);
$stmt->execute();
$stmt->store_result();
$stmt->fetch();

Can this be changed to count not only the number of parts (pj_part) but also count the number of galleries and photos from their respective tables? I'm trying to streamline my queries and learn more about making my code efficient. Any help would be sincerely appreciated.

UPDATE:

I'm not certain how to do the table structure formatting here, but here it is in plain text:

pj_parts
pj_part_id (primary key)
pj_id (project number)
pj_part (part number within project)

pj_part_galleries
pj_gallery_id (primary key)
pj_id (project number)
pj_part (part number within project)
pj_gallery (gallery number)

pj_photos
pj_photo_id (primary key)
pj_id (project number)
pj_part (part number within project)
pj_gallery_number

I hope this helps, if not, please let me know what to do to reformat it.

Upvotes: 0

Views: 144

Answers (3)

Jim
Jim

Reputation: 22656

How about something like:

SELECT 
COUNT(DISTINCT p.pj_part_id) AS parts,
COUNT(DISTINCT g.pj_gallery_id) AS galleries,
COUNT(DISTINCT ph.pj_photo_id) AS photos,
 FROM 
pj_parts p
LEFT JOIN pj_part_galleries g ON (g.pj_part = p.pj_part_id)
LEFT JOIN pj_part_photos ph ON (ph.pj_part = p.pj_part_id)
WHERE p.pj_id = ?

You'll have to add in the correct table/column names.

Edit: If using mysqli you can do the following to bind: Replace:

$stmt->bind_result($galTotal);

With:

$stmt->bind_result($partsTotal,$galleriesCount,$photosCount);

NB: Here I've changed $galTotal to $partsTotal.

Edit2: Updated to use column/table names.

Upvotes: 1

D Stanley
D Stanley

Reputation: 152566

Guessing on your structure, but something like this?

SELECT 
    COUNT(DISTINCT p.part_id) parts ,
    COUNT(DISTINCT g.gal_id) galleries ,
    COUNT(DISTINCT ps.pic_id) photos
FROM pj_parts p
    LEFT JOIN {galleries} g on p.part_id = g.part_id
    LEFT JOIN {photos} ps on g.gal_id = ps.gal_id
WHERE p.pj_id = ?

Upvotes: 1

Popnoodles
Popnoodles

Reputation: 28409

If you use UNION

SELECT 'pj_parts' as tablename, COUNT(*) as c 
    FROM pj_parts WHERE something=something
UNION 
SELECT 'pj_galleries' as tablename, COUNT(*) as c 
    FROM some_other_table WHERE something=something
UNION 
SELECT 'pj_photos' as tablename, COUNT(*) as c 
    FROM some_other_other_table WHERE something=something

you'll get this

tablename         |   c
------------------+--------
pj_parts          |  3
pj_galleries      |  5
pj_photos         |  302

which you can iterate through to perhaps populate an array or whatever (question doesn't specify)

Upvotes: 2

Related Questions