Add results from several COUNT queries - sql

I am trying to fetch the sum of several counts in one query:
SELECT(
SELECT COUNT( * )
FROM comments +
SELECT COUNT( * )
FROM tags +
SELECT COUNT( * )
FROM search
)
I am missing something here. I get syntax error.

SELECT ( SELECT COUNT(*) FROM comments )
+ ( SELECT COUNT(*) FROM tags )
+ ( SELECT COUNT(*) FROM search )

One more (not sure if supported with MySQL, though - works in SQL Server):
SELECT SUM(Counts) FROM
(SELECT COUNT(*) AS Counts FROM COMMENTS UNION ALL
SELECT COUNT(*) FROM Tags UNION ALL
SELECT COUNT(*) FROM Search) s

SELECT (
SELECT COUNT(*)
FROM comments
) +
(
SELECT COUNT(*)
FROM tags
) +
(
SELECT COUNT(*)
FROM search
)

SELECT SUM(ThisCount)
FROM (
SELECT COUNT(*) AS ThisCount
FROM comments
UNION ALL
SELECT COUNT(*) AS ThisCount
FROM tags
UNION ALL
SELECT COUNT(*) AS ThisCount
FROM search
)

Related

How do I use MIN on a union column SQL

I'm having problems with using the MIN function in sql. I want to get a list of all the rows with the minimum value from my count function.
Here is my code:
SELECT land, MIN(count) as lowest
FROM
(
SELECT temp.land, count(*)
FROM
(
SELECT grans.land FROM Grans
UNION ALL
SELECT grans.aland FROM Grans
) as temp
GROUP BY land
ORDER BY land
) as subQuery
GROUP BY land
ORDER BY land
At the moment I just get a table listing land and count, although count is renamed to lowest.
I would use window functions:
SELECT land, cnt
FROM (SELECT temp.land, count(*) as cnt,
MIN(count(*)) OVER () as min_cnt
FROM (SELECT grans.land FROM Grans
UNION ALL
SELECT grans.aland FROM Grans
) temp
GROUP BY land
) l
WHERE cnt = min_cnt;
remove group by if you just want min because if you put group by it will return all the land count that you got in your sub-query, as in count it already made group and that is distinct
SELECT *
FROM
(
SELECT temp.land, count(*) as cnt
FROM
(
SELECT grans.land FROM Grans
UNION ALL
SELECT grans.aland FROM Grans
) as temp
GROUP BY land
ORDER BY land
) as subQuery
order by cnt asc
Limit 1
another way is
SELECT temp.land, count(*) as cnt
FROM
(
SELECT grans.land FROM Grans
UNION ALL
SELECT grans.aland FROM Grans
) as temp
GROUP BY land
having cnt in(
SELECT min(cnt)
FROM
(
SELECT temp.land, count(*) as cnt
FROM
(
SELECT grans.land FROM Grans
UNION ALL
SELECT grans.aland FROM Grans
) as temp
GROUP BY land
ORDER BY land
) as subQuery
)
and it also work
select * from
(
SELECT * ,row_number() over(partition by land order by cnt) as rn
FROM
(
SELECT temp.land, count(*) as cnt
FROM
(
SELECT grans.land FROM Grans
UNION ALL
SELECT grans.aland FROM Grans
) as temp
GROUP BY land
ORDER BY land
) as subQuery
) t where t.rn=1

How to divide the count() of two seperate queries in DB2

So I have
select count(*) from ( "query1")
select count(*) from ( "query2")
I want to divide the two and get the floating point result.
I was told to use something like this
SELECT (COUNT(smtg) * 1.0) / COUNT(smtg)
But Im not sure
You can just do:
select q1.cnt * 1.0 / q2.cnt
from (select count(*) as cnt from ( "query1") ) q1 cross join
(select count(*) as cnt from ( "query2") ) q2;
Or, if you prefer:
select ( (select count(*) from ( "query1")) * 1.0 /
(select count(*) from ( "query2"))
)
from sysibm.sysdummy1;
other solution (be carefull to not divide by 0)
with
query1 as (select count(*) as nb1 from ( "query1")),
query2 as (select count(*) as nb2 from ( "query2"))
select case when nb2=0 then null else nb1* 1.0/nb2 end as Result
from query1, query2

Select rows with same ID/email but different value in other table

Select rows with same ID/email but different value in other table
I have two tables: person and email, now there are mail addresses that have the same value, and persons/ID with different values.
Can anyone tell how to write an SQL query for this? I have tried but I can't figure it out. I have found some answers but then it is always finding the match in the same table
Like this
Table_person. ​​Table_email
1​​​ email#persoon1
2​​​ email#persoon2
3​​​ email#persoon3
4​​​ email#persoon1
5​​​ email#persoon5
6​​​ email#persoon2
The output should be
Table_person​​ Table_email
1​​​ email#persoon1
4​​​ email#persoon1
2​​​ email#persoon2
6​​​ email#persoon2
Using a common table expression with row_number()
;with cte as (
select *
, rn = row_number() over (partition by email order by person_id)
from email e
)
select *
from cte
where exists (
select 1
from cte i
where i.email = cte.email
and rn > 1
)
or using exists()
select *
from email e
where exists (
select 1
from email i
where i.email = e.email
and i.person_id <> e.person_id
)
rextester demo: http://rextester.com/JHFEF82373
Hope it will helps you
;with cte(Table_person,​​Table_email)
AS
(
SELECT 1​​​,'email#persoon1' UNION ALL
SELECT 2​​​,'email#persoon2' UNION ALL
SELECT 3​​​,'email#persoon3' UNION ALL
SELECT 4​​​,'email#persoon1' UNION ALL
SELECT 5​​​,'email#persoon5' UNION ALL
SELECT 6​​​,'email#persoon2'
)
,Cte2
AS
(
SELECT Table_person,​​Table_email From
(
Select Table_person,​​Table_email,ROW_NUMBER()OVER(Partition by Table_email Order By Table_person )Seq
from cte
)dt WHERE dt.Seq>1
)
,Final
AS
(
SELECT Table_person,​​Table_email From
(
Select Table_person,​​Table_email,ROW_NUMBER()OVER(Partition by Table_email Order By Table_email )Seq2
from cte
)dt
where dt.Seq2>1
Union ALL
SELECT Table_person,​​Table_email From cte2
)
SELECt Table_person,​​Table_email from Final

Finding duplicates with two similar columns and one distinct

I am in a situation where I need to select rows that have the same content in two specific columns, AND distinct content in a third one. So far I got this for the two similar columns:
SELECT id, Title,
COUNT(*) AS NumOccurrences
FROM Table
GROUP BY id, Title
HAVING ( COUNT(*) > 1 )
I now need to specify a third distinct column in this query. Let's call it Ralph. This obviously does not work:
SELECT id, Title, DISTINCT Ralph,
COUNT(*) AS NumOccurrences
FROM Table
GROUP BY id, Title
HAVING ( COUNT(*) > 1 )
So what will?
select * from (
SELECT id, Title, COUNT(*) AS NumOccurrences
FROM Table t
GROUP BY id, Title
HAVING ( COUNT(*) > 1 )
) t
cross apply (
select distinct Ralph
from Table
where id = t.id and Title = t.Title
) t2
You can use COUNT(*) with OVER() clause
;WITH cte AS
(
SELECT id, Title, Ralph, COUNT(*) OVER (PARTITION BY id, Title) AS cnt
FROM dbo.test11
GROUP BY id, Title, Ralph
)
SELECT *
FROM cte
WHERE cnt > 1
Demo on SQLFiddle

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