How to sum rowcounts - sql

How would I count the number of rows in three tables and return the sum of the three row counts?

This will return every table count on your db just add the WHERE to filter the ones you want
http://www.dba-oracle.com/t_count_rows_all_tables_in_schema.htm
select
table_name,
to_number(
extractvalue(
xmltype(
dbms_xmlgen.getxml('select count(*) c from '||table_name))
,'/ROWSET/ROW/C')) row_count
from
user_tables
order by
table_name;
Just include this in a CTE to get the SUM
WITH cte AS (
select
table_name,
to_number(
extractvalue(
xmltype(
dbms_xmlgen.getxml('select count(*) c from '||table_name))
,'/ROWSET/ROW/C')) row_count
from
user_tables
WHERE table_name in ('table1', 'table2', 'table3' )
)
SELECT SUM(row_count)
FROM cte

select sum(rowcount) from
(
select count(*) as rowcount from tablea a
UNION
select count(*) from tableb b
UNION
select count(*) from tablec c
)

Since the number of rows of a table is returned as a single row result, you could cross the join the three results and sum them with the + operator:
SELECT a.cnt + b.cnt + c.cnt
FROM (SELECT COUNT(*) AS cnt FROM table_a) a
CROSS JOIN (SELECT COUNT(*) AS cnt FROM table_b) b
CROSS JOIN (SELECT COUNT(*) AS cnt FROM table_c) c

select sum(v.cnt) as total_sum
from
(select count (*) as cnt from <<table1>>
union all
select count (*) as cnt from <<table2>>
union all
select count (*) as cnt from <<table3>>) v

select
cnt1 + cnt2 + cnt3
as mycnt
from
(SELECT COUNT (*) as cnt1 FROM s1.t1),
(SELECT COUNT (*) as cnt2 FROM s1.t2),
(SELECT COUNT (*) as cnt3 FROM s1.t3)
Is what I ended up using. Thanks all.

Related

Sum the count(*) of between three tables

I want to sum the number of counts between 3 tables. I have added three input fields to give a specific date each time but I am struggling on how to SUM the COUNTS(*)
select count(*)
from db.table1
where call_date = ${var:call_date};
select count(*)
from db.table2
where call_date = ${var:call_date};
select count(*)
from db.table3
where call_date= ${var:call_date};
thanks in advance
You can simply use them as sub-query as follows:
select (select count(*) from db.table1 where call_date = ${var:call_date})
+ (select count(*) from db.table2 where call_date = ${var:call_date})
+ (select count(*) from db.table3 where call_date= ${var:call_date})
as rslt;
UNION ALL the selects. SUM() the result.
select sum(cnt) from
(
select count(*) cnt
from db.table1
where call_date = ${var:call_date}
UNION ALL
select count(*)
from db.table2
where call_date = ${var:call_date}
UNION ALL
select count(*)
from db.table3
where call_date= ${var:call_date}
) dt

Identify duplicates rows based on multiple columns

#SQL Experts,
I am trying to fetch duplicate records from SQL table where 1st Column and 2nd Column values are same but 3rd column values should be different.
Below is my table
ID NAME DEPT
--------------------
1 VRK CSE
1 VRK ECE
2 AME MEC
3 BMS CVL
From the above table , i am trying to fetch first 2 rows, below is the Query, suggest me why isn't give correct results.
SELECT A.ID, A.NAME, A.DEPT
FROM TBL A
INNER JOIN TBL B ON A.ID = B.ID
AND A.NAME = B.NAME
AND A.DEPT <> B.DEPT
Somehow I am not getting the expected results.
Your sample data does not make it completely clear what you want here. Assuming you want to target groups of records having duplicate first/second columns with all third column values being unique, then we may try:
SELECT ID, NAME, DEPT
FROM
(
SELECT ID, NAME, DEPT,
COUNT(*) OVER (PARTITION BY ID, NAME) cnt,
MIN(DEPT) OVER (PARTITION BY ID, NAME) min_dept,
MAX(DEPT) OVER (PARTITION BY ID, NAME) max_dept
FROM yourTable
) t
WHERE cnt > 1 AND min_dept = max_dept;
UPDATE
select *
from
(
select *,
COUNT(*) over (partition by id, [name]) cnt1,
COUNT(*) over (partition by id, [name], dept) cnt2
from dbo.T
) x
where x.cnt1 > 1 and x.cnt2 < x.cnt1;
For find duplicate column
select x.id, x.name, count(*)
from
(select distinct a.id, a.name, a.dept
from tab a) x
group by x.id, x.name
having count(*) > 1
If you want the original rows, I would just go for exists:
select t.*
from tbl t
where exists (select 1
from tbl t
where t2.id = t.id and t2.name = t.name and
t2.dept <> t.dept
);
If you just want the id/name pairs:
select t.id, t.name
from tbl t
group by t.id, t.name
having min(t.dept) <> max(t.dept);

SQL:How to select the first record from duplicate rows?

While Executing the below query to find the duplicate
select * from (
select a.* ,count (*) over (partition by a.ID) as tot
from HREMP a
) tt
where tt.tot >1
its returning 423 rows,
I executed another query to find non duplicate record
select * from (
select a.* ,count (*) over (partition by a.ID) as tot
from HREMP a
) tt
where tt.tot =1
Its returning 685 records
I found that there are 196 distinct records among the 423 duplicate
Now, How to select the first record from duplicate records?
select distinct *
from ( select a.*, count(*) over (partition by a.ID) as tot
from HREMP a
) tt
where tt.tot > 1
or
select *
from ( select a.*
, count(*) over (partition by a.ID) as tot
, row_number() over (partition by a.ID order by 1) as rn
from HREMP a
) tt
where tt.tot > 1
and tt.rn = 1

alias table with union all not works

I have ora-00094 (identifier not valid) in a simple query but I can't see why. Could you help me please?
select columnA, 'More than 4000 bytes'
from tableA
union all
select p.columnB, listagg(p.columnC, ',') within group (order by p.columnC)
from (
select distinct b.job_name, a.hostname
from tableB a, emuser.def_job b
) p
group by p.columnB
order by p.columnB desc;
ORDER BY is for ResultSet of whole query. So for ORDER BY there is no columnB here. ResultSet have only column names of first query.
Try this
SELECT columnA, 'More than 4000 bytes' as columnC FROM tableA
UNION ALL
SELECT p.columnB, LISTAGG (p.columnC, ',') WITHIN GROUP (ORDER BY p.columnC)
FROM (SELECT DISTINCT b.job_name, a.hostname
FROM tableB a, emuser.def_job b) p
GROUP BY p.columnB
ORDER BY p.columnA DESC;

Select count(*) from multiple tables

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
SELECT (
SELECT COUNT(*)
FROM tab1
) AS count1,
(
SELECT COUNT(*)
FROM tab2
) AS count2
FROM dual
As additional information, to accomplish same thing in SQL Server, you just need to remove the "FROM dual" part of the query.
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.
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.
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
/
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
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).
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.
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.
SELECT (SELECT COUNT(*) FROM table1) + (SELECT COUNT(*) FROM table2) FROM dual;
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 :)
select (select count(*) from tab1) count_1, (select count(*) from tab2) count_2 from dual;
--============= 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
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
)
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)
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 );
SELECT (
SELECT COUNT(*)
FROM tbl1
)
+
(
SELECT COUNT(*)
FROM tbl2
)
as TotalCount
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
select
(select count() from tab1 where field like 'value') +
(select count() from tab2 where field like 'value')
count
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