SQL - counting WHERE AGGREGATE>1 [duplicate] - sql

This question already has answers here:
SQL - WHERE AGGREGATE>1
(3 answers)
Closed 9 years ago.
Imagine I have a db table of Customers containing {id,username,firstname,lastname}
If I want to find how many instances there are of different firstnames I can do:
select firstname, count(*) from Customers group by 2 order by 1;
firstname | count(*)
====================
bob | 1
jeff | 2
adam | 5
How do I count the number of firstnames that occur more than once? In pseudo-sql it would be something like:
select
COUNT(
firstname,
count(*) as num_occurrences
)
from
Customers
group by 2
having num_occurrences > 1;

You have the right idea:
SELECT COUNT(*)
FROM (
SELECT firstname
FROM Customers
GROUP BY firstname
HAVING COUNT(*) >= 2
)
The subquery counts the first names that have occurred more than once. Then you count all of those first names. The HAVING clause allows you to filter by aggregates. It's like a WHERE clause, except you can use aggregate functions.

There is no need for a subquery.
Try:
SELECT firstname, COUNT(*)
FROM Customers
GROUP BY firstname
HAVING COUNT(*) > 1
ORDER BY firstname
Or, order by the most represented name:
SELECT firstname, COUNT(*) AS custcount
FROM Customers
GROUP BY firstname
HAVING COUNT(*) > 1
ORDER BY custcount DESC;

This would do it:
select count(username)
from (select username
from Customers
group by username
having count(*) > 1);

Related

How can i do it in single SQL?

I have this Table like this
ID | NAME | AGE | ADDRESS | SALARY
and an ID (2)
AGE of ID 2 is 25,
Now i need to count total number of record with AGE 25. How can i do it in single SQL Query? is there any why?
i currently doing it in 2 query. in one i return AGE with ID.
select AGE from table_name where ID = 2
it return AGE 25
and 2nd query i count number of record with this AGE.
select COUNT(*) from table_name where age =25
i want to do it in one SQL Query. is there any way ?
use SQL COUNT function
select COUNT(*) from mytable where age =25
You want to count the number of rows with the same age as the specified ID?
You can use a windowed count
select Agecount
from (
select *, Count(*) over (partition by Age) Agecount
from YourTable
)t
where id=?
Use Group by with subquery
SELECT COUNT(*) AS ageCount
FROM table_name
WHERE age in (SELECT age FROM table_name WHERE ID = 2)
GROUP BY age
For Questions like this the best way is use multiple conditions using Where keyword with And-Or Operators.
This query should work for your requirement without complicating anything.
select count(*) from table_name where ID=2 and age=25;

sql duplicates showing all data

Given this data
id Name group
1 Jhon 001
2 Paul 002
3 Mary 001
How can I get the duplicates values showing all the fields? The duplicate is only on group, id and name won't be duplicates.
Should end up looking like one of those (any would be valid):
:::::::::::::::::::::::::::::::::::::::::::::::
group count values
001 2 1,3
:::::::::::::::::::::::::::::::::::::::::::::::
id name group
1 Jhon 001
3 Mary 001
I tried with
SELECT
group, COUNT(*)
FROM
people
GROUP BY
group
HAVING
COUNT(*) > 1
But if I try to add id and name to the group by, it won´t find any duplicate.
Thanks in advance.
Try this.
SELECT Id, Name, [Group]
FROM people
WHERE [Group] IN(
SELECT [Group]
FROM people
GROUP BY [Group]
HAVING COUNT(*) > 1)
I would do an inner query to find the groups with more than one member, and then use that inner query to bring back a list of the names.
For example:
SELECT Id, Name, group
FROM people
WHERE group in
(SELECT group
FROM people
GROUP BY group
HAVING count(*) > 1);
Avoid using Group because it is a reserved keyword in SQL :
SELECT *
FROM MyTable
WHERE groups IN(
SELECT groups
FROM MyTable
GROUP BY groups
HAVING COUNT(*) > 1)
Check Execution here
Just use exists:
select p.*
from people p
where exists (select 1
from people p2
where p2.group = p.group and
p2.id <> p.id
);
This should be the most performant solution. With an index on people(group, id), it should have very good performance.
Note: All the advice to avoid using group as a column name is good advice. You should change the name.

Display column values next to each other SQL

I have to select which wards have patients with the same last name. I need to display the name of those patients and the IDs that come with them.
My query below works to give me the proper result:-
SELECT pt.NAME, pt.PATIENTID, pt.PATIENTID
FROM PATIENT pt
WHERE pt.NAME IN
(SELECT pt.NAME
FROM PATIENT pt
GROUP BY pt.NAME
HAVING COUNT(DISTINCT pt.WARDNO) < 2)
AND NAME IN
(SELECT NAME
FROM PATIENT
GROUP BY NAME
HAVING COUNT(*) > 1)
It gives me the following result in the table:
Name | PatientID
Jones | p10
Jones | p29
However, I want to display my results in the table like this and am not sure how.
Name | PatientID | PatientID
Jones | p10 | p29
Assuming you expect no more than two patient ID values, then a simple aggregation can work here:
WITH cte AS (
SELECT NAME
FROM PATIENT
GROUP BY NAME
HAVING COUNT(*) > 1 AND COUNT(DISTINCT WARDNO) < 2
)
SELECT
NAME,
MIN(PATIENTID) AS PatientID1,
MAX(PATIENTID) AS PatientID2
FROM cte
GROUP BY
NAME;
Thank you Tim. That aggregation did work and I did a little tweak to make it a lot cleaner. It works to display just the two PatientIDs which is what I need for now.
My new query is as follows
SELECT pt.NAME, MIN(pt.PATIENTID) AS PAT, MAX(pt.PATIENTID) AS PAT
FROM PATIENT pt
GROUP BY pt.NAME
HAVING COUNT(*) > 1 AND COUNT(DISTINCT pt.WARDNO) < 2
However, if I do have multiple PatientIDs I am curious what I would do.
I have to select which wards have patients with the same last name.
Assuming patients are not duplicated, you can get the patient/ward combinations as:
select p.wardno, p.name, count(*)
from patient p
group by p.wardno, p.name
having count(*) >= 2;
If you only want the wards, then you have one of the rare situations where select distinct and group by are appropriate:
select distinct p.wardno
from patient p
group by p.wardno, p.name
having count(*) >= 2;

Count single occurrences of a row item

I would like to count the number of times an item in a column has appeared only once. For example if in my table I had...
Name
----------
Fred
Barney
Wilma
Fred
Betty
Barney
Fred
...it would return me a count of 2 because only Wilma and Betty have appeared once.
Here is SQLFiddel Demo
Below is the Query which you can try:
select count(*) from
(select Name
from Table1
group by Name
having count(*) = 1) T
Till Above my post was for your actual Post.
Below is the post for modified question:
In oracle you can try below query:
select sum(count(rownum))
from Table1
group by "Name"
having count(*) = 1
OR
Here is SQLFiddel Demo
In SQL Server you can try below query:
SELECT COUNT(*)
FROM Table1 a
LEFT JOIN Table1 b
ON a.Name=b.Name
AND a.%%physloc%% <> b.%%physloc%%
WHERE b.Name IS NULL
OR
Here is the SQLFiddel Demo
In Sybase you can try below query:
select count(count(name))
from table
group by name
having count(name) = 1
as per #user2617962's answer.
Thank you
select count(*) from
(select count(*) from Table1
group by Name
having count(*) =1) s
SqlFiddle
Since you just need the count of column values appearing once without the actual value of the column, the query should be:
select count(count(name)) from table group by name having count(name)
= 1
Try following.
select name from (select name, count(name) as num from tblUsers group by name)
tblTemp where tblTemp.num=1
Mark it if this works..:)

SQL - WHERE AGGREGATE>1

Imagine I have a db table of Customers containing {id,username,firstname,lastname}
If I want to find how many instances there are of different firstnames I can do:
select firstname,count(*) from Customers group by 2 order by 1;
username | count(*)
===================
bob | 1
jeff | 2
adam | 5
How do I write the same query to only return firstnames that occur more than once? i.e. in the above example only return the rows for jeff and adam.
You want the having clause, like so:
select
firstname,
count(*)
from Customers
group by firstname
having count(*) > 1
order by 1
group by 2 order by 1 is terrible, I should say. Use proper column names if that's supported: this will drastically improve readability.
With that in mind,
select firstname, count(*) c
from Customers
group by firstname
having count(*) > 1 -- Kudos to Shannon
order by c;
That's what the HAVING clause does. I'm not sure if this will work in informix, but give it a shot:
select firstname, count(*)
from Customers
group by firstname
HAVING COUNT(*) > 1