MySQL SELECT combining 3 SELECTs INTO 1

Posted by Martin Tóth on Stack Overflow See other posts from Stack Overflow or by Martin Tóth
Published on 2010-05-26T12:04:23Z Indexed on 2010/05/28 11:51 UTC
Read the original article Hit count: 238

Filed under:

Consider following tables in MySQL database:

entries:
    creator_id INT
    entry TEXT
    is_expired BOOL
other:
    creator_id INT
    entry TEXT

userdata:
    creator_id INT
    name VARCHAR
    etc...

In entries and other, there can be multiple entries by 1 creator. userdata table is read only for me (placed in other database).

I'd like to achieve a following SELECT result:

+------------+---------+---------+-------+
| creator_id | entries | expired | other |
+------------+---------+---------+-------+
|      10951 |      59 |      55 |    39 | 
|      70887 |      41 |      34 |   108 | 
|      88309 |      38 |      20 |   102 | 
|      94732 |       0 |       0 |    86 |

... where entries is equal to SELECT COUNT(entry) FROM entries GROUP BY creator_id, expired is equal to SELECT COUNT(entry) FROM entries WHERE is_expired = 0 GROUP BY creator_id and other is equal to SELECT COUNT(entry) FROM other GROUP BY creator_id.

I need this structure because after doing this SELECT, I need to look for user data in the "userdata" table, which I planned to do with INNER JOIN and select desired columns.

I solved this problem with selecting "NULL" into column which does not apply for given SELECT:

SELECT
    creator_id,
    COUNT(any_entry) as entries,
    COUNT(expired_entry) as expired,
    COUNT(other_entry) as other
FROM (
    SELECT
        creator_id,
        entry AS any_entry,
        NULL AS expired_entry,
        NULL AS other_enry
    FROM entries
    UNION
    SELECT
        creator_id,
        NULL AS any_entry,
        entry AS expired_entry,
        NULL AS other_enry
    FROM entries
    WHERE is_expired = 1
    UNION
    SELECT
        creator_id,
        NULL AS any_entry,
        NULL AS expired_entry,
        entry AS other_enry
    FROM other
) AS tTemp
GROUP BY creator_id
ORDER BY
    entries DESC,
    expired DESC,
    other DESC
;

I've left out the INNER JOIN and selecting other columns from userdata table on purpose (my question being about combining 3 SELECTs into 1).

  • Is my idea valid? = Am I trying to use the right "construction" for this?
  • Are these kind of SELECTs possible without creating an "empty" column? (some kind of JOIN)
  • Should I do it "outside the DB": make 3 SELECTs, make some order in it (let's say python lists/dicts) and then do the additional SELECTs for userdata?

Solution for a similar question does not return rows where entries and expired are 0.

Thank you for your time.

© Stack Overflow or respective owner

Related posts about mysql