How to sum duplicates SQL/PSQL - sql

I have some problem with how to build a query to sum all duplicates, in this query below I can count all occurrences.
SELECT COUNT (*) occurrences
FROM back.submission s
GROUP BY s.name
HAVING COUNT(*) > 1
----------
|# |occurrences|
|1 | 9 |
|2 | 6 |
|3 | 5 |
|4 | 4 |
|5 | 4 |
|6 | 3 |
....
I would like to know how to sum all occurrences, i tried to put count inside SUM, but it doesn't work

Do you want an other level of aggregation?
SELECT COUNT(occurences) AS count_of_duplicates, SUM(occurences) AS sum_of_duplicates
FROM (
SELECT COUNT (*) occurrences
FROM back.submission s
GROUP BY s.name
HAVING COUNT(*) > 1
) t

SELECT #,count(*) As Total FROM back.submission GROUP BY # HAVING COUNT(*) > 1;

With CTE
As
(
Select [#],Count([*]) As Total From back.submission Group By [#]
)
select [#],Total From CTE Where Total>1

Related

Output several counts of one table records in one row

Here is an example table CALLRECORD:
+--------+------------+
|callid | rating |
|1 | |
|2 | 5 |
|3 | |
|4 | 1 |
|5 | |
+--------+------------+
No problem to output total number of calls, number of rated calls, average rating and number of unrated calls:
select count(*) as total from callrecord;
select count(*) as rated, avg(rating) as average_rating from callrecord where rating is not null;
select count(*) as unrated from callrecord where rating is null;
+--------+
|total |
|5 |
+--------+
+--------+------------+
|rated |average |
|2 |3 |
+--------+------------+
+--------+
|unrated |
|3 |
+--------+
I'm looking for how to output all above to one row with single SQL request:
+--------+--------+------------+---------+
|total |rated |average |unrated |
|5 |2 |3 |3 |
+--------+--------+------------+---------|
db<>fiddle here
Most aggregate functions ignore null values, so what you want is simpler that you may think:
select
count(*) total, -- total number of rows
count(rating) as rated, -- count of non-null ratings
avg(rating) average, -- avg ignore `null`
count(*) - count(rating) unrated -- count of null ratings
from mytable
Try using the SUM aggregation with a CASE statement inside of it. Example below.
Select
COUNT(*) AS 'Total',
SUM(CASE WHEN rating IS NULL THEN 0 ELSE 1 END) AS 'Rated',
(SUM(CASE WHEN rating IS NULL THEN 0 ELSE rating END)/SUM(CASE WHEN rating IS NULL THEN 0 ELSE 1 END)) AS 'Avg',
SUM(CASE WHEN rating IS NULL THEN 1 ELSE 0 END) AS 'Unrated'
From callrecord

How to make MS SQL select on this

I have MS SQL database table like this
TableA
+----+-----------+--------+
|ID | Table2_FK | Value |
+----+-----------+--------+
|1 | 7 | X |
|2 | 7 | Y |
|3 | 8 | X |
|4 | 8 | Z |
|5 | 9 | W |
|6 | 9 | M |
|5 | 10 | X |
|6 | 10 | Z |
+----+-----------+--------+
I want to make query to get list of Table2_FKs if I pass X and Z in query for Values. In this example 8 and 10 is the result
It can be more than 2 values
You can do this with group by and having:
select table2_fk
from t
where value in ('X', 'Z')
group by table2_fk
having count(*) = 2;
If the values can be duplicated for a key value, then use count(distinct value) = 2. The "2" is the number of values in the IN list.
Try this:
select distinct Table2_FK
from TableA
where value in ('X','Z');
You can use query as below:
Select distinct table2_fk from (
Select *, Ct = count(id) over (partition by table2_fk) from yourtable
) a
Where a.[Value] in ('X','Z') and a.Ct >= 2
you can use a query like below
select
distinct Table2_FK
from TableA a
where exists (
select 1 1 from TableA b where b.value ='X' and a.Table2_FK =b.Table2_FK
)
and exists (
select 1 1 from TableA c where c.value ='Z' and a.Table2_FK =c.Table2_FK
)

Sum the result of count()

I have a table like this.
-----------------
|City |Block |
-----------------
|Bekasi |A1 |
|Bekasi |A1 |
|Jakarta |A1 |
|Jakarta |A2 |
|Bandung |A3 |
-----------------
What is the correct query if I want to count subtotal of Bekasi's block as 1, Jakarta's block as 2 and Bandung's block as 1, so it will return total values like this?
-----------------
|City |Block |
-----------------
|Bekasi |A1 |
|Bekasi |A1 |
|Jakarta |A1 |
|Jakarta |A2 |
|Bandung |A3 |
-----------------
|TOTAL |4 |
-----------------
I tried using this query
SELECT COUNT(DISTINCT block) AS total FROM report GROUP BY city
But it will only return a result like this.
--------
|Total |
--------
|1 |
|1 |
|2 |
--------
Please help me, thanks.
This will give you the sum of the total count
select SUM(a.total)
from
(SELECT COUNT(DISTINCT block) AS total FROM report GROUP BY city) a
And if you want the data and total in the same query you could do something like this:
select 1 as rank, city, count(city) from report group by city
union all
select 2 as rank, 'Total', SUM(a.total)
from
(SELECT COUNT(DISTINCT block) AS total FROM report GROUP BY city) a
order by rank asc
Try This
select City,count(distinct Block) from report group by City With RollUp
select count (t) from (
select city,count(block) as t from report group by city, block) s
group by city

Percentage of requests SQL

So, I have this table:
Table1
|Number | abc |
|100 | No |
|200 | No |
|300 | Yes |
|400 | No |
|500 | No |
What I want is the percentage of values that is "yes". In this case, the desired OUTPUT is 20%
I thought that by dividing the number of "yes" by the total number It would do it, but i can't "join" all things.
I know that the number of "yes" is
select count(abc)
from table1
where abc='yes'
And the total number is
select count(*)
from table1
How do i get the desired output?
A query that works in all SQL engines is
select sum(case when abc = 'yes' then 1 else 0 end) * 100 / count(*)
from your_table

How can I count how much each different values occur in each column independently?

Given table mytable with two columns letter and num
letter|num
------+------
a |1
a |1
b |1
b |2
I tried doing
SELECT letter, count(letter), num, count(num) from mytable group BY letter, num;
but it returns
letter|count|num |count
------+-----+------+-----
b | 1 | 1 | 1
a | 2 | 1 | 2
b | 1 | 2 | 1
whereas I wanted
letter|count|num |count
------+-----+------+-----
a | 2 | 1 | 3
b | 2 | 2 | 1
Is this possible to do, and can I do it in one query?
You could change it to 2 separate aggregates like this.
SELECT 'letter' as type, letter AS item, count(letter)
from mytable group BY letter
UNION ALL --CAST to be same type as letter
SELECT 'num', CAST(num AS varchar(100)), count(num)
from mytable group BY num;