Filter on count(*) in oracle - sql

I have a grouped query, and would like to filter it based on count(*)
Can I do this without a subquery?
This is what I have currently:
select *
from (select ID,
count(*) cnt
from name
group by ID)
where cnt > 1;

what you are looking for is the HAVING clause:
select ID, count(*) cnt
from name
group by ID
having count(*) > 1;

Related

Find Duplicate records where one field is different in SQL

I want to find duplicate ticket_id where source column is different but ticket_id is same (see below picture which records are in red)
Here is the table structure
This is what I have tried
SELECT ticket_id, SOURCE, COUNT(ticket_id) AS NumOccurrences
FROM mytable
GROUP BY ticket_id, SOURCE
HAVING ( COUNT(ticket_id) > 1 )
This should work:
SELECT d.Ticket_ID, COUNT(*)
FROM(
SELECT DISTINCT Ticket_ID, Source
FROM dups
) d GROUP BY ticket_id
HAVING COUNT(*) > 1
If you want the query to return the Ticket_ID and the Source, then you can do this:
SELECT a.* FROM dups a
JOIN(
SELECT d.Ticket_ID, count(*)
FROM(
SELECT distinct Ticket_ID, Source
FROM dups
) d GROUP BY ticket_id
HAVING COUNT(*) > 1
) b on a.Ticket_ID = b.Ticket_ID
You can group on ticket_id and filter on only ones that have a distinct count of source greater than 1.
SELECT *
FROM mytable
WHERE Ticket_ID IN (
SELECT Ticket_ID
FROM mytable
GROUP BY Ticket_ID
HAVING COUNT(DISTINCT Source) > 1)
The above returns the actual rows. If you just need counts you could
SELECT Ticket_ID, COUNT(1)
FROM mytable
GROUP BY Ticket_ID
HAVING COUNT(DISTINCT source) > 1

Select duplicated data from table

Query
select * from table1
where having count(reference)>1
I want to select * the data which have duplicate data,any idea why my query is not working?
Below are my expect result..
You can make use of window function count to find number of rows per id and reference and then filter to get those which have count more than 1.
;with cte as (
select t.*, count(*) over (partition by id, reference) cnt
from table1 t
)
select * from cte where cnt > 1;
Demo
In the above solution, I have made an assumption that name and id has one to one correspondence (which is true as per your given data). If that's not the case, add name too in the partition by clause:
;with cte as (
select t.*, count(*) over (partition by name, id, reference) cnt
from table1 t
)
select * from cte where cnt > 1;
I might actually approach this by using a subquery with GROUP BY:
SELECT t1.*
FROM table1 t1
INNER JOIN
(
SELECT Name, ID, reference
FROM table1
GROUP BY Name, ID, reference
HAVING COUNT(*) > 1
) t2
ON t1.Name = t2.Name AND
t1.ID = t2.ID AND
t1.reference = t2.reference
Demo here:
Rextester
Try this ), first i get count by partition, after that i get row with count > 1
select No, Name, ID, Reference
from (select count(*) over (partition by name, ID, reference) cnt, table1.* from table1)
where cnt>1
The easy way (although maybe not the best for performance) would be:
select * from table1 where reference in (
select reference from table1 group by reference having count(*)>1
)
In a subselect you have the duplicated data, and in the outter select you have all the data for these references.

Group by and Count to select repeated rows

I wrote this query but it does not work as I expected.
1st Goal: select rows that have repeated in certain columns and return whole columns.
2nd Goal: Update a flag (a column) to identify which records have repeated.
Could you please help me?
SELECT
*
FROM AvvalV2NS AS M
WHERE EXISTS
(SELECT
M.Astate,
M.Acity,
M.Azone,
M.Abvillage,
M.Avillage,
COUNT(*)
FROM AvvalV2NS AS M
GROUP BY M.Astate,
M.Acity,
M.Azone,
M.Abvillage,
M.Avillage
HAVING COUNT(*) > 1)
If you want to get the rows that are duplicated, window functions are probably the easiest way:
select a.*
from (select a.*,
count(*) over (partition by M.Astate, M.Acity, M.Azone, M.Abvillage, M.Avillage) as cnt
from AvvalV2NS a
) a
where cnt > 1;
You can update a flag by doing something like this:
with toupdate as (
select a.*
from (select a.*,
count(*) over (partition by M.Astate, M.Acity, M.Azone, M.Abvillage, M.Avillage) as cnt
from AvvalV2NS a
) a
)
update toupdate
set isduplicate = (case when cnt > 1 then 1 else 0 end);
Suppose your table have an id column:
SELECT * FROM THE_TABLE WHERE ID IN (
SELECT ID FROM
(SELECT ID, REPEATING_COLUMNS, COUNT(*) FROM THE_TABLE GROUP BY REPEATING_COLUMNS HAVING COUNT(*) > 1)
)
UPDATE THE_TABLE SET THE_FLAG = "HERE WE GO" WHERE ID IN (
SELECT ID FROM
(SELECT ID, REPEATING_COLUMNS, COUNT(*) FROM THE_TABLE GROUP BY REPEATING_COLUMNS HAVING COUNT(*) > 1)
)
Hope this helps.

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

Error : aggregate may not appear in the WHERE clause

I'm trying to get the max of column:
select * from
( select col1, count(*) as cnt from talbe1
group by col1
) dt
where cnt = max(cnt)
I tried to get exact value and it worked such as:
where cnt = 5
or
where cnt > 3
that was OK so what is wrong with the first query?
Edit: the numbers I put there (5, 3) are completely random, I want to get the maximum number of cnt.
Aggregate clauses have to go in the HAVING section. However, this won't work with your query as is. What you probably wanted to do was:
select top 1 col1, count(*) as cnt
from talbe1
group by col1
order by count(*) desc
You can do this with HAVING clause. For example if you want to get cnt=3 records
Select col1, count(*) as cnt from talbe1
Group by col1
Having count(*)=3
If you want to get MAX(cnt)
Select Top(1) col1, count(*) as cnt from talbe1
Group by col1
Order by cnt desc
I found a solution,
it was pretty simple:(I should have focused more)
select max(cnt) from
( select Fld301, count(*) as cnt from TbC3
group by Fld301
) dt
How about this query:
select * from
(
select
col1,
count(*) as cnt,
RANK() OVER(ORDER BY count(*) DESC) AS ran
from talbe1
group by col1
) dt
where ran=1