Oracle'daki bir tabloda yinelenen değerleri nasıl bulabilirim?


276

Belirli bir sütun için yinelenen değerleri ve Oracle veritabanı tablosundaki oluşumlarının sayısını döndürecek en basit SQL ifadesi nedir?

Örneğin: Sütunlu bir JOBStablo var JOB_NUMBER. Yinelenen JOB_NUMBERs olup olmadığımı ve kaç kez çoğaltıldıklarını nasıl öğrenebilirim?


Yanıtlar:


609
SELECT column_name, COUNT(column_name)
FROM table_name
GROUP BY column_name
HAVING COUNT(column_name) > 1;

1
Teşekkürler - bulduğum cevap bu ve beni buraya geri göndermem için yendin! : o)
Andrew

3
Rica ederim. Şimdi count (sütun) ve count (*) arasındaki farklar hakkında kendi sorumu göndermek üzereyim. :)
Kertenkele Bill

44
4 yıldan fazla bir süre sonra +1, yine de iyi çalışır ve şu şekilde olduğu sürece birden fazla sütun seçmek için ayarlanabilir group by: select column_one, column_two, count(*) from tablename group by column_one, column_two having count(column_one) > 1;vb.
Amos M. Carpenter

4
hatta çift having count(*) > 1: D
Stanislav Mamontov

3
8 yıldan fazla bir süre sonra +1, hem Oracle'ın hem de MySQL'in en son sürümleri için iyi çalışır (satırda sayma işlevinden sonra alanı kaldırın).
PhatHV

58

Diğer yol:

SELECT *
FROM TABLE A
WHERE EXISTS (
  SELECT 1 FROM TABLE
  WHERE COLUMN_NAME = A.COLUMN_NAME
  AND ROWID < A.ROWID
)

İndeks açık olduğunda (yeterince hızlı) iyi çalışır column_name. Ve yinelenen satırları silmenin veya güncellemenin daha iyi bir yolu.


3
+1, çok sütunlu kopyalar için iyi çalışır (örneğin, birkaç sütuna UNIQUE kısıtlaması eklemek istediğinizde), bu yaklaşımı, yinelenen alan değerlerini + gerekirse diğer alanları listelemek için GROUP BY'dan daha az "katı" buldum.
Frosty Z

3
Sadece açıklığa kavuşturmak için, (bu ilk başta benim için açık değildi) bu sorgu sadece kopyaları döndürür, ilk orijinal girişi döndürmez, bu nedenle kopyaları silmek için iyi çalışır. 1 sütun. Bu sorgu ile yinelenen kimlikleri seçebilir ve daha sonra kopyaları silmek için bunları kullanabilirsiniz.
matthewb

1
<olarak! = değiştirirseniz, yinelenen tüm kayıtları alırsınız. sadece 2. veya 3. kayıt değil
moore1emu

33

Düşünebileceğim en basit:

select job_number, count(*)
from jobs
group by job_number
having count(*) > 1;

1
Tüm sütunları nasıl alabilirim?
Asif Mushtaq

2
job_number'ın bulunduğu işlerden * seçin (count (*)> 1 olan job_number'a göre jobs grubundan job_number'ı seçin)
JosephStyons

17

Gerçek kopya sayısını bilmeniz gerekmiyorsa, döndürülen sütunlarda sayıya sahip olmanız gerekmez. Örneğin

SELECT column_name
FROM table
GROUP BY column_name
HAVING COUNT(*) > 1

7

Nasıl olur:

SELECT <column>, count(*)
FROM <table>
GROUP BY <column> HAVING COUNT(*) > 1;

Yukarıdaki örneği cevaplamak için şöyle görünecektir:

SELECT job_number, count(*)
FROM jobs
GROUP BY job_number HAVING COUNT(*) > 1;

5

Birden fazla sütunun benzersiz satırı (ör. İlişkiler tablosu) tanımlaması durumunda, aşağıdakileri kullanabilirsiniz

Emp_dept (empid, deptid, startdate, enddate) satır kimliğini kullanın. Empid ve deptid öğelerinin benzersiz olduğunu varsayalım ve bu durumda satırı tanımlar

select oed.empid, count(oed.empid) 
from emp_dept oed 
where exists ( select * 
               from  emp_dept ied 
                where oed.rowid <> ied.rowid and 
                       ied.empid = oed.empid and 
                      ied.deptid = oed.deptid )  
        group by oed.empid having count(oed.empid) > 1 order by count(oed.empid);

ve bu tabloda birincil anahtar varsa, rowid yerine birincil anahtar kullanın, örneğin id pk

select oed.empid, count(oed.empid) 
from emp_dept oed 
where exists ( select * 
               from  emp_dept ied 
                where oed.id <> ied.id and 
                       ied.empid = oed.empid and 
                      ied.deptid = oed.deptid )  
        group by oed.empid having count(oed.empid) > 1 order by count(oed.empid);

4

select count(j1.job_number), j1.job_number, j1.id, j2.id
from   jobs j1 join jobs j2 on (j1.job_numer = j2.job_number)
where  j1.id != j2.id
group by j1.job_number

size yinelenen satırların kimliklerini verecektir.


4
SELECT   SocialSecurity_Number, Count(*) no_of_rows
FROM     SocialSecurity 
GROUP BY SocialSecurity_Number
HAVING   Count(*) > 1
Order by Count(*) desc 

2

Genellikle Oracle Analitik işlevini ROW_NUMBER () kullanıyorum .

Eğer benzersiz bir dizin veya sütunların üzerine inşa birincil anahtar (ilgili olarak sahip sen çiftleri kontrol etmek istediğiniz Say c1, c2, c3). Sonra yetiştirme, bu şekilde gidecek ROWIDgetirdiği hatlarının sayısı satır s ROW_NUMBER()ise >1:

Select * From Table_With_Duplicates
      Where Rowid In
                    (Select Rowid
                       From (Select Rowid,
                                    ROW_NUMBER() Over (
                                            Partition By c1 || c2 || c3
                                            Order By c1 || c2 || c3
                                        ) nbLines
                               From Table_With_Duplicates) t2
                      Where nbLines > 1)

1

İşte bunu yapmak için bir SQL isteği:

select column_name, count(1)
from table
group by column_name
having count (column_name) > 1;

1

Onun eski bir iplik biliyorum ama bu bazı yardımcı olabilir.

Aşağıdaki yinelenen kullanımı kontrol ederken tablonun diğer sütunlarını yazdırmanız gerekiyorsa:

select * from table where column_name in
(select ing.column_name from table ing group by ing.column_name having count(*) > 1)
order by column_name desc;

ayrıca gerekirse yan tümceye bazı ek filtreler de ekleyebilirsiniz.


0

1. çözüm

select * from emp
    where rowid not in
    (select max(rowid) from emp group by empno);

Bu orijinal poster silinmekten hiç bahsetmedi, sadece sayıyor
Jeff

-1

Ayrıca u bir tablodaki tüm yinelenen değerleri listelemek için reqitem demek için böyle bir şey deneyebilirsiniz

SELECT count(poid) 
FROM poitem 
WHERE poid = 50 
AND rownum < any (SELECT count(*)  FROM poitem WHERE poid = 50) 
GROUP BY poid 
MINUS
SELECT count(poid) 
FROM poitem 
WHERE poid in (50)
GROUP BY poid 
HAVING count(poid) > 1;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.