SQL Sum of Counts and Group By - sql

I have a table with 2 columns:
ID Status
-- -------
1 OK
2 OK
3 NOTOK
4 NOTOK
5 OK
I want to do a count and group by status and also have the sum of the count on each row. The count works but I do not know how to do the sum to appear on each row like this:
Status Count TotalCount
------- ----- ------
OK 3 5
NOTOK 2 5

SELECT COUNT(*) AS Count, SUM(*) AS Sum FROM *your table* GROUP BY Status.
You can use AS to rename whatever you want. I think sum will appear now.

select distinct Status, count(*) occurrences, count(*) over(partition by Status) total_count from table group by Status

You can use two windowed counts:
select distinct status,
Count(*) over(partition by status) as "count",
Count(*) over() as "Sum"
from t;
without window functions you could take various approaches, one would be
with c as (
select status, Count(*) as "Count"
from t
group by status
)
select *, (select Sum("count") from c) as "Sum"
from c
And in case CTE's are not supported...
select *, (select Count(*) from t) as "Sum"
from (
select status, Count(*) as "Count"
from t
group by status
)c

Use a subquery.
SELECT Status, COUNT(*) as Count, (SELECT COUNT(*) FROM my_table) AS TotalCount FROM my_table GROUP BY Status;
SQL Fiddle

Related

Finding top count of a value in a table using SQL

I'm looking for a way to find the top count value of a column by SQL.
If for example this is my data
id type
----------
1 A
1 B
1 A
2 C
2 D
2 D
I would like the result to be:
1 A
2 D
I'm looking for a way to do it without groping by the column I count (type in the example)
Thanks
Statistically, this is called the "mode". You can calculate it using window functions:
select id, type, cnt
from (select id, type, count(*) as cnt,
row_number() over (partition by id order by count(*) desc) as seqnum
from t
group by id, type
) t
where seqnum = 1;
If there are ties, then an arbitrary value is chosen from among the ties.
You are looking for the statistic mode (the most often ocurring value):
select id, stats_mode(type)
from mytable
group by id
order by id;
Not all DBMS support this however. Check your docs, wheher this function or a similar one is available in your DBMS.
Just GROUP BY id, type and keep the rows with the maximum counter:
select id, type
from tablename
group by id, type
having count(*) = (
select count(*) from tablename group by id, type order by count(*) desc limit 1
)
See the demo
Or
select id, type
from tablename
group by id, type
having count(*) = (
select max(t.counter) from (select count(*) counter from tablename group by id, type) t
)
See the demo

Query 2 sum in 1 table

table a
column id : a a b b
column total : 1 2 1 3
how can i show? in one table without use compute
a 3 7
b 4 7
Do group by to sum each id's total. Do a sub-select to count total:
select id,
sum(total) as total,
(select sum(total) from a) as totalall
from a
group by id
Using window functions with a distinct, it can be simply expressed like this:
select distinct id,
sum(Total) over(partition by id) total,
Sum(Total) over () total_all
from mytable
SQL Fiddle
One way is to use OUTER APPLY. You could also set a variable to the sum of the table and call that variable.
select a.id, sum(a.total) as total, b.Grand as GrandTotal
from tablea a
outer apply
(select sum(total) as Grand from tablea) b
group by a.id

SUM of grouped COUNT in SQL Query

I have a table with 2 fields:
ID Name
-- -------
1 Alpha
2 Beta
3 Beta
4 Beta
5 Charlie
6 Charlie
I want to group them by name, with 'count', and a row 'SUM'
Name Count
------- -----
Alpha 1
Beta 3
Charlie 2
SUM 6
How would I write a query to add SUM row below the table?
SELECT name, COUNT(name) AS count
FROM table
GROUP BY name
UNION ALL
SELECT 'SUM' name, COUNT(name)
FROM table
OUTPUT:
name count
-------------------------------------------------- -----------
alpha 1
beta 3
Charlie 2
SUM 6
SELECT name, COUNT(name) AS count, SUM(COUNT(name)) OVER() AS total_count
FROM Table GROUP BY name
Without specifying which rdbms you are using
Have a look at this demo
SQL Fiddle DEMO
SELECT Name, COUNT(1) as Cnt
FROM Table1
GROUP BY Name
UNION ALL
SELECT 'SUM' Name, COUNT(1)
FROM Table1
That said, I would recomend that the total be added by your presentation layer, and not by the database.
This is a bit more of a SQL SERVER Version using Summarizing Data Using ROLLUP
SQL Fiddle DEMO
SELECT CASE WHEN (GROUPING(NAME) = 1) THEN 'SUM'
ELSE ISNULL(NAME, 'UNKNOWN')
END Name,
COUNT(1) as Cnt
FROM Table1
GROUP BY NAME
WITH ROLLUP
Try this:
SELECT ISNULL(Name,'SUM'), count(*) as Count
FROM table_name
Group By Name
WITH ROLLUP
all of the solution here are great but not necessarily can be implemented for old mysql servers (at least at my case). so you can use sub-queries (i think it is less complicated).
select sum(t1.cnt) from
(SELECT column, COUNT(column) as cnt
FROM
table
GROUP BY
column
HAVING
COUNT(column) > 1) as t1 ;
Please run as below :
Select sum(count)
from (select Name,
count(Name) as Count
from YourTable
group by Name); -- 6
The way I interpreted this question is needing the subtotal value of each group of answers. Subtotaling turns out to be very easy, using PARTITION:
SUM(COUNT(0)) OVER (PARTITION BY [Grouping]) AS [MY_TOTAL]
This is what my full SQL call looks like:
SELECT MAX(GroupName) [name], MAX(AUX2)[type],
COUNT(0) [count], SUM(COUNT(0)) OVER(PARTITION BY GroupId) AS [total]
FROM [MyView]
WHERE Active=1 AND Type='APP' AND Completed=1
AND [Date] BETWEEN '01/01/2014' AND GETDATE()
AND Id = '5b9xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' AND GroupId IS NOT NULL
GROUP BY AUX2, GroupId
The data returned from this looks like:
name type count total
Training Group 2 Cancelation 1 52
Training Group 2 Completed 41 52
Training Group 2 No Show 6 52
Training Group 2 Rescheduled 4 52
Training Group 3 NULL 4 10535
Training Group 3 Cancelation 857 10535
Training Group 3 Completed 7923 10535
Training Group 3 No Show 292 10535
Training Group 3 Rescheduled 1459 10535
Training Group 4 Cancelation 2 27
Training Group 4 Completed 24 27
Training Group 4 Rescheduled 1 27
You can use union to joining rows.
select Name, count(*) as Count from yourTable group by Name
union all
select "SUM" as Name, count(*) as Count from yourTable
For Sql server you can try this one.
SELECT ISNULL([NAME],'SUM'),Count([NAME]) AS COUNT
FROM TABLENAME
GROUP BY [NAME] WITH CUBE
with cttmp
as
(
select Col_Name, count(*) as ctn from tab_name group by Col_Name having count(Col_Name)>1
)
select sum(ctn) from c
You can use ROLLUP
select nvl(name, 'SUM'), count(*)
from table
group by rollup(name)
Use it as
select Name, count(Name) as Count from YourTable
group by Name
union
Select 'SUM' , COUNT(Name) from YourTable
I am using SQL server and the following should work for you:
select cast(name as varchar(16)) as 'Name', count(name) as 'Count'
from Table1
group by Name
union all
select 'Sum:', count(name)
from Table1
I required having count(*) > 1 also. So, I wrote my own query after referring some the above queries
SYNTAX:
select sum(count) from (select count(`table_name`.`id`) as `count` from `table_name` where {some condition} group by {some_column} having count(`table_name`.`id`) > 1) as `tmp`;
Example:
select sum(count) from (select count(`table_name`.`id`) as `count` from `table_name` where `table_name`.`name` IS NOT NULL and `table_name`.`name` != '' group by `table_name`.`name` having count(`table_name`.`id`) > 1) as `tmp`;
You can try group by on name and count the ids in that group.
SELECT name, count(id) as COUNT FROM table group by name
After the query, run below to get the total row count
select ##ROWCOUNT
select sum(s) from
(select count(Col_name) as s from Tab_name group by Col_name having count(*)>1)c

SELECT MAX of COUNT

I have a table "well". It contains a column app_rate_unit (type: nvarchar).
My goal is to count every distinct value in the table and let the DBMS (MS Server 2005) give me the most occurring one.
This is my code:
SELECT MAX(app_rate_unit) AS MAX_APP
FROM (SELECT app_rate_unit, COUNT(*) AS co
FROM dbo.well AS w
GROUP BY app_rate_unit
) AS derivedtbl_1
The poblem with it is however, that my DBMS actually delivers the lowest count to me.
SideQuestion: How do I filter for a foreign key (in the table) and NOT NULL (in app_rate_unit) when counting?
select top 1 app_rate_unit, count(*) from dbo.well
group by app_rate_unit
order by count(*) desc
Try this
SELECT
COUNT(app_rate_unit)AS MAX_APP ,
app_rate_unit
FROM
dbo.well
WHERE
app_rate_unit IS NOT NULL
GROUP BY
app_rate_unit
ORDER BY
MAX_APP DESC
The above script will give you the count and the item. You can change the count if you are not sure only one item will have the maximum number of occurrence.
select top 1 count(*) as co from dbo.well as w group by app_rate_unit
order by count(*) desc
In PostgreSQL we can write query which using max of count as
select max(count) from (
select count(id) from Table _name group by created_by,status_id having status_id = 6 ) as Alias
eg
select max(count) from (
select count(id) from orders group by created_by,status_id having status_id = 6 ) as foo

how to calculate count in sql?

I have the following table:
memberid
2
2
3
4
3
...and I want the following result:
memberid count
2 2
3 1 ---Edit by gbn: do you mean 2?
4 1
I was attempting to use:
SELECT MemberID,
COUNT(MemberID)
FROM YourTable
GROUP BY MemberID
...but now I want find which record which has maximum count. IE:
memberid count
2 2
SELECT memberid, COUNT(*) FROM TheTable GROUP BY memberid
Although, it won't work for your desired output because you have "memberid = 3" twice.
Edit: After late update to question...
SELECT TOP 1 WITH TIES --WITH TIES will pick up "joint top".
memberid, COUNT(*)
FROM
TheTable
GROUP BY
memberid
ORDER BY
COUNT(*) DESC
SELECT MemberID, COUNT(MemberID) FROM YourTable GROUP BY MemberID
What if there is a tie (or more) for the max? Do you want to display one or all?
This is how I would do this
SELECT memberid, COUNT(1)
FROM members
GROUP BY memberid
HAVING COUNT(1) = (
SELECT MAX(result.mem_count)
FROM (
SELECT memberid, COUNT(1) as mem_count
FROM members
GROUP BY memberid
) as result
)
I would love to see a more efficient approach though.
Do it like this:
SELECT memberid, COUNT(memberid) AS [count] FROM [Table] GROUP BY memberid
This should do the trick with no subselects required:
select top 1 memberid, COUNT(*) as counted
from members
group by memberid
order by counted desc
Can be done quite easy:
SELECT TOP 1 MemberId, COUNT(*) FROM YourTable GROUP BY MemberId ORDER By 2 DESC
I believe the original poster requested 2 result sets.
The only way I know of to get this (in SQL Server) is to dump the original records into a temp table and then do a SELECT and MAX on that. I do welcome an answer that requires less code!
-- Select records into a temp table
SELECT
Table1.MemberId
,CNT = COUNT(*)
INTO #Temp
FROM YourTable AS Table1
GROUP BY Table1.MemberId
ORDER BY Table1.MemberId
-- Get original records
SELECT * FROM #Temp
-- Get max. count record(s)
SELECT
Table1.MemberId
,Table1.CNT
FROM #Temp AS Table1
INNER JOIN (
SELECT CNT = MAX(CNT)
FROM #Temp
) AS Table2 ON Table2.CNT = Table1.CNT
-- Cleanup
DROP TABLE #Temp
How about this query:
SELECT TOP 1 MemberID,
COUNT(MemberID)
FROM YourTable
GROUP BY MemberID
ORDER by count(MemberID) desc
SELECT count(column_name)
FROM your_table;
You need to use a subselect:
SELECT MemberID, MAX(Count) FROM
(SELECT MemberID, COUNT(MemberID) Count FROM YourTable GROUP BY MemberID)
GROUP BY MemberID
The second group by is needed to return both, the count and the MemberID.