300

How can I select count(*) from two different tables (call them tab1 and tab2) having as result:

Count_1   Count_2
123       456

I've tried this:

select count(*) Count_1 from schema.tab1 union all select count(*) Count_2 from schema.tab2

But all I have is:

Count_1
123
456
Hash
  • 4,647
  • 5
  • 21
  • 39
user73118
  • 3,011
  • 2
  • 17
  • 4

21 Answers21

423
SELECT  (
        SELECT COUNT(*)
        FROM   tab1
        ) AS count1,
        (
        SELECT COUNT(*)
        FROM   tab2
        ) AS count2
FROM    dual
Quassnoi
  • 413,100
  • 91
  • 616
  • 614
100

As additional information, to accomplish same thing in SQL Server, you just need to remove the "FROM dual" part of the query.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dincerm
  • 1,455
  • 1
  • 9
  • 9
  • 3
    I was just getting ready to say "But what about MS SQL, when I saw your comment. Thank you for anticipating the need! – Andrew Neely May 29 '12 at 12:52
64

Just because it's slightly different:

SELECT 'table_1' AS table_name, COUNT(*) FROM table_1
UNION
SELECT 'table_2' AS table_name, COUNT(*) FROM table_2
UNION
SELECT 'table_3' AS table_name, COUNT(*) FROM table_3

It gives the answers transposed (one row per table instead of one column), otherwise I don't think it's much different. I think performance-wise they should be equivalent.

Mike Woodhouse
  • 51,832
  • 12
  • 88
  • 127
  • 2
    You'd better put UNION ALL here. – Quassnoi Mar 03 '09 at 20:31
  • What difference could adding "ALL" make with three single row queries? The results must be the same either way, surely? – Mike Woodhouse Mar 04 '09 at 07:04
  • 1
    UNION without ALL groups results. If there are 2 rows in table_1 and table_2, and 3 rows in table_3, you'll get two rows in your resultset, and won't be able to tell from resultset how many rows does table_2 have: 2 or 3. – Quassnoi Mar 04 '09 at 10:40
  • 6
    Yes, but I select the table name, which makes the results unique. Otherwise you'd be correct, but what value would there be in several numbers without context? ;-) – Mike Woodhouse Mar 04 '09 at 12:17
  • This is also a good way to use a CTE (WITH SELECT) statement for each count. – blue_chip Sep 16 '19 at 21:06
36

My experience is with SQL Server, but could you do:

select (select count(*) from table1) as count1,
  (select count(*) from table2) as count2

In SQL Server I get the result you are after.

Nic Wise
  • 8,061
  • 2
  • 31
  • 30
17
    select 
    t1.Count_1,t2.Count_2
    from 
(SELECT count(1) as Count_1 FROM tab1) as t1, 
(SELECT count(1) as Count_2 FROM tab2) as t2
Vikas Kumar
  • 1,683
  • 14
  • 15
17

Other slightly different methods:

with t1_count as (select count(*) c1 from t1),
     t2_count as (select count(*) c2 from t2)
select c1,
       c2
from   t1_count,
       t2_count
/

select c1,
       c2
from   (select count(*) c1 from t1) t1_count,
       (select count(*) c2 from t2) t2_count
/
David Aldridge
  • 51,479
  • 8
  • 68
  • 96
11

A quick stab came up with:

Select (select count(*) from Table1) as Count1, (select count(*) from Table2) as Count2

Note: I tested this in SQL Server, so From Dual is not necessary (hence the discrepancy).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
CJM
  • 11,908
  • 20
  • 77
  • 115
9

For a bit of completeness - this query will create a query to give you a count of all of the tables for a given owner.

select 
  DECODE(rownum, 1, '', ' UNION ALL ') || 
  'SELECT ''' || table_name || ''' AS TABLE_NAME, COUNT(*) ' ||
  ' FROM ' || table_name  as query_string 
 from all_tables 
where owner = :owner;

The output is something like

SELECT 'TAB1' AS TABLE_NAME, COUNT(*) FROM TAB1
 UNION ALL SELECT 'TAB2' AS TABLE_NAME, COUNT(*) FROM TAB2
 UNION ALL SELECT 'TAB3' AS TABLE_NAME, COUNT(*) FROM TAB3
 UNION ALL SELECT 'TAB4' AS TABLE_NAME, COUNT(*) FROM TAB4

Which you can then run to get your counts. It's just a handy script to have around sometimes.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chris Gill
  • 2,848
  • 5
  • 26
  • 31
  • I like the answer but I think you should add the owner to the "FROM"-part of the query. Otherwise you have to execute the query with the owner which might not directly be available. – Christopher Gertz Mar 17 '21 at 16:05
8

SELECT (SELECT COUNT(*) FROM table1) + (SELECT COUNT(*) FROM table2) FROM dual;

casperOne
  • 73,706
  • 19
  • 184
  • 253
8

Here is from me to share

Option 1 - counting from same domain from different table

select distinct(select count(*) from domain1.table1) "count1", (select count(*) from domain1.table2) "count2" 
from domain1.table1, domain1.table2;

Option 2 - counting from different domain for same table

select distinct(select count(*) from domain1.table1) "count1", (select count(*) from domain2.table1) "count2" 
from domain1.table1, domain2.table1;

Option 3 - counting from different domain for same table with "union all" to have rows of count

select 'domain 1'"domain", count(*) 
from domain1.table1 
union all 
select 'domain 2', count(*) 
from domain2.table1;

Enjoy the SQL, I always do :)

Taryn
  • 242,637
  • 56
  • 362
  • 405
Fadzil
  • 83
  • 1
  • 4
8

As I can't see any other answer bring this up.

If you don't like sub-queries and have primary keys in each table you can do this:

select count(distinct tab1.id) as count_t1,
       count(distinct tab2.id) as count_t2
    from tab1, tab2

But performance wise I believe that Quassnoi's solution is better, and the one I would use.

Jimmy Stenke
  • 11,140
  • 2
  • 25
  • 20
6
--============= FIRST WAY (Shows as Multiple Row) ===============
SELECT 'tblProducts' [TableName], COUNT(P.Id) [RowCount] FROM tblProducts P
UNION ALL
SELECT 'tblProductSales' [TableName], COUNT(S.Id) [RowCount] FROM tblProductSales S


--============== SECOND WAY (Shows in a Single Row) =============
SELECT  
(SELECT COUNT(Id) FROM   tblProducts) AS ProductCount,
(SELECT COUNT(Id) FROM   tblProductSales) AS SalesCount
Sheikh Kawser
  • 136
  • 2
  • 6
6
select (select count(*) from tab1) count_1, (select count(*) from tab2) count_2 from dual;
Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
5

If the tables (or at least a key column) are of the same type just make the union first and then count.

select count(*) 
  from (select tab1key as key from schema.tab1 
        union all 
        select tab2key as key from schema.tab2
       )

Or take your satement and put another sum() around it.

select sum(amount) from
(
select count(*) amount from schema.tab1 union all select count(*) amount from schema.tab2
)
2
Declare @all int
SET @all = (select COUNT(*) from tab1) + (select count(*) from tab2)
Print @all

or

SELECT (select COUNT(*) from tab1) + (select count(*) from tab2)
Rabby Hasan
  • 356
  • 4
  • 10
0

JOIN with different tables

SELECT COUNT(*) FROM (  
SELECT DISTINCT table_a.ID  FROM table_a JOIN table_c ON table_a.ID  = table_c.ID   );
zloctb
  • 10,592
  • 8
  • 70
  • 89
0
SELECT  (
        SELECT COUNT(*)
        FROM   tbl1
        )
        +
        (
        SELECT COUNT(*)
        FROM   tbl2
        ) 
    as TotalCount
Chag
  • 31
  • 5
0

If you're using Google BigQuery this will work.

SELECT
  date,
  SUM(Table_1_Id_Count) AS Table_1_Id_Count,
  SUM(Table_2_Id_Count) AS Table_2_Id_Count
FROM
  (
    SELECT
      Id AS Table_1_Id,
      date,
      COUNT(Id) AS Table_1_Id_Count,
      0 AS Table_2_Id_Count
    FROM
      `your_project_name.Table_1`
    GROUP BY
      Id,
      date
    UNION ALL
    SELECT
      Id AS Table_2_Id,
      date,
      0 AS Table_1_Id_Count,
      COUNT(Id) AS Table_2_Id_Count
    FROM
      `your_project_name.Table_2`
    GROUP BY
      Id,
      date
  )
GROUP BY
  date
daniellambert
  • 109
  • 1
  • 8
0

You need subqueries:

Select t1.key, t1.col, t2.col, 
    , (Select count(*)
        From table3
        Where key = t1.key) as Count1
    , (Select count(*)
        From table4
        Where key = t1.key) as Count2
From table1 t1
Join table2 t2 on t2.key = t1.key
Where t1.key in (1,2,3)
Andrew Gale
  • 101
  • 1
  • 4
-1

select (select count() from tab1 where field like 'value') + (select count() from tab2 where field like 'value') count

Cris
  • 2,824
  • 24
  • 23
-2
select @count = sum(data) from
(
select count(*)  as data from #tempregion
union 
select count(*)  as data from #tempmetro
union
select count(*)  as data from #tempcity
union
select count(*)  as data from #tempzips
) a
Taryn
  • 242,637
  • 56
  • 362
  • 405
sajid
  • 1