简体   繁体   中英

Selecting one record from two tables and multiple records from another table in ONE query

As of now I have 4 tabels (that are relevant to this question); pictures , photographers , models & picture_models .

A picture can only have 1 photographer but multiple models. In the pictures table there is a photographer_id column, which can be found in the photographers table as well.

I want to select everything from the pictures table (with a specific pictures.picture_id ), everything from the photographers table and then every model that have been assigned to the photo in picture_models . The picture_models table looks like this;

   Table: picture_models
   `picture_id` int(10) unsigned NOT NULL,
   `model_id` int(10) unsigned NOT NULL

So every picture can have more than one record in picture_models . Back to my question.. is it possible to somehow select models.* together with the picture info and photographer info. As of now, my query looks like this;

    SELECT p.*,
           ph.*,
           COUNT(pv.vote) vote_count,
           SUM(pv.vote) vote_sum,
           (SELECT COUNT(vote) FROM picture_votes WHERE vote > 0 AND picture_id = ?) plus_votes,
           (SELECT COUNT(vote) FROM picture_votes WHERE vote < 0 AND picture_id = ?) minus_votes
              FROM pictures p
                 LEFT JOIN picture_votes pv
                    ON pv.picture_id = p.picture_id
                 LEFT JOIN photographers ph
                    ON p.photographer_id = ph.photographer_id
                 WHERE p.authenticated = 1
                    AND
                 p.picture_id = ?

Is it pointless/impossible to do what I want? Would it better to just do another query selecting all models exclusively?

You can do something like this; you'll a copy of the picture/vote data for each model. This can be more efficient than doing two separate queries, especially if the number of models is low.

You might need to expand ph.* into individual columns, as without it there will be two photographer_id columns in the inner query, which may not be allowed. Also, a lot of databases would expect a group by p.*, ph.* with all the columns in the inner query. I think MySQL will let you away with it, though.

Select
    p.*,
    m.*
From (
    Select
        p.*,
        ph.*,
        count(pv.vote) vote_count,
        sum(pv.vote) vote_sum,
        sum(case when pv.vote > 0 Then 1 else 0 end) plus_votes,
        sum(case when pv.vote < 0 then 1 else 0 end) minus_votes
    From
        pictures p
            left join
        picture_votes pv
            On pv.picture_id = p.picture_id
            left join
        photographers ph
            On p.photographer_id = ph.photographer_id
    Where
        p.authenticated = 1 And
        p.picture_id = ?
    ) p
        left join
    picture_models m
        On p.model_id = m.model_id

Thanks to @Laurence's answer I was able to come up with this;

SELECT
    p.*,
    m.*
    FROM (
        SELECT
            p.*,
             ph.photographer_name,
             ph.photographer_website,
             ph.photographer_instagram,
             ph.photographer_facebook,
             ph.photographer_twitter,
             ph.photographer_googleplus,
            pm.model_id,
            COUNT(pv.vote) vote_count,
            SUM(pv.vote) vote_sum,
            SUM(CASE WHEN pv.vote > 0 THEN 1 ELSE 0 END) plus_votes,
            SUM(CASE WHEN pv.vote < 0 THEN 1 ELSE 0 END) minus_votes
        FROM
            pictures p
                LEFT JOIN
            picture_votes pv
                    ON pv.picture_id = p.picture_id
                LEFT JOIN
            picture_models pm
                    ON pm.picture_id = p.picture_id
                LEFT JOIN
            photographers ph
                    ON ph.photographer_id = p.photographer_id
        WHERE
            p.authenticated = 1
                AND
            p.picture_id = 1
        GROUP BY
            pm.model_id
        ) p
    LEFT JOIN
        models m
            ON p.model_id = m.model_id

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM