7

This seems like it should be simple and doable but I'm not smart. I'm trying to sum up the count of hosts across multiple databases on the same server with a single query. The databases to sum up the host count are themselves derived from a query.

get a list of databases:

mysql> select name from db1.companies where status = 'active';
+---------------------+
| name                |
+---------------------+
| companyA            |
| companyB            |
| companyC            |
...

Get the total sum of the host count from each database:

SUM(
select count(id) from companyA.hosts
select count(id) from companyB.hosts
select count(id) from companyC.hosts
...
)

2 Answers 2

3

You have to use a prepared statement to get at the desired result:

SELECT
  GROUP_CONCAT(
    CONCAT(
      '(SELECT count(id) FROM `',
      name,
      '`.`hosts`)') SEPARATOR ' + ')
FROM
  db1.companies
WHERE
  status = 'active'
INTO @sql;

SET @sql := CONCAT('SELECT ', @sql);

SELECT @sql;

PREPARE stmt FROM @sql;
EXECUTE stmt;

Output from SELECT @sql:

@sql
-------------------------------------------------------------------------
SELECT (SELECT count(id) FROM `companyA`.`hosts`) + 
       (SELECT count(id) FROM `companyB`.`hosts`) + 
       (SELECT count(id) FROM `companyC`.`hosts`)

So, @sql variable holds the dynamic sql statement that needs to be executed in order to obtain the desired result.

Demo here

Sign up to request clarification or add additional context in comments.

3 Comments

Great, thanks Giorgos! I had to make one change and remove the "`" from around the <database>.hosts else I received this error: ERROR 1146 (42S02): Table 'test.companyA.hosts' doesn't exist
@bighorchata This was a bug that I fixed afterwards. Never mind, the statement can also be executed without the '`' characters.
Thanks again, much appreciated
1

Assuming that the database names are correct and each database holds a table called Hosts, we still need to include the schema name in the query. So just replace the <schema> with the schema name you have and run the below query and you should get the sum.

 ;WITH CTE AS (

select count(id) AS [HostSum] from companyA.<schema>.hosts
UNION ALL
select count(id) AS [HostSum] from companyB.<schema>.hosts
UNION ALL
select count(id) AS [HostSum] from companyC.<schema>.hosts

)

SELECT SUM([HostSum]) AS [HostSum] FROM CTE

if you cant use a common table expression then you can use the following:

SELECT SUM([HostSum]) AS [HostSum] FROM (

    select count(id) AS [HostSum] from companyA.<schema>.hosts
    UNION ALL
    select count(id) AS [HostSum] from companyB.<schema>.hosts
    UNION ALL
    select count(id) AS [HostSum] from companyC.<schema>.hosts

    ) AS A

6 Comments

Unfortunately MySQL does not support WITH clause. I should have made that clear that this is mysql (beyond the tag i already have)
MySQL doesn't support the WITH clause (CTE in SQL Server parlance; Subquery Factoring in Oracle)
@bighorchata how about my second suggestion
@KamranFarzami: So you stole my answer? great!
@haytem your answer would not work because you have not specified the schema. so in essence your answer is wrong.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.