oracle - selekcja duplikatow bazujac na kilku kryteriach
pawelcs - 17-05-2006 00:41
oracle - selekcja duplikatow bazujac na kilku kryteriach
Witam,
Mam nastepujacy problem. Potrzebuje znalezc wszytskie duplikaty w tabeli. Duplikatami sa rekordy w ktorych trzy z pieciu wybranych kolumn przechowuja takie same wartosci (case insensative). przyklad: kolumny brane pod uwage: lastname, firstname, company, postalcode, email
i mamy trzy rekordy:
id, lastname, firstname, company, postalcode, email, phone 1, Kowalski, Jan, BMX, 30300, kowalski@cos.pl, 6111111 2. Kowalski, Jan, CRS, 20567, kowalski@crs.pl, 6578905 3. Kowalski, Adam, CRS, 30300, kowalski@cos.pl, 7444444
to jako duplikat powinny byc zakwalifikowane rekordy o id 1 i 3
Ktos ma pomysl na jakiegos SQL'a?
Slawomir Cichy - 17-05-2006 00:41
pawelcs wrote: > Witam, > > Mam nastepujacy problem. Potrzebuje znalezc wszytskie duplikaty w > tabeli. Duplikatami sa rekordy w ktorych trzy z pieciu wybranych kolumn > przechowuja takie same wartosci (case insensative). > przyklad: > kolumny brane pod uwage: > lastname, firstname, company, postalcode, email > > i mamy trzy rekordy: > > id, lastname, firstname, company, postalcode, email, phone > 1, Kowalski, Jan, BMX, 30300, kowalski@cos.pl, 6111111 > 2. Kowalski, Jan, CRS, 20567, kowalski@crs.pl, 6578905 > 3. Kowalski, Adam, CRS, 30300, kowalski@cos.pl, 7444444 > > to jako duplikat powinny byc zakwalifikowane rekordy o id 1 i 3 > > Ktos ma pomysl na jakiegos SQL'a? >
select * from tabela where (postalcode, email) in (select postalcode, email from ( select count(*) as ile, postalcode, email from tabela group by postalcode, email ) where ile > 1)
pozdrawiam Slawas
=?UTF-8?B?UGF3ZcWCIE1hdGVqc2tp?= - 17-05-2006 00:41
pawelcs wrote: > Witam, > > Mam nastepujacy problem. Potrzebuje znalezc wszytskie duplikaty w > tabeli. Duplikatami sa rekordy w ktorych trzy z pieciu wybranych kolumn > przechowuja takie same wartosci (case insensative). > przyklad: > kolumny brane pod uwage: > lastname, firstname, company, postalcode, email > > i mamy trzy rekordy: > > id, lastname, firstname, company, postalcode, email, phone > 1, Kowalski, Jan, BMX, 30300, kowalski@cos.pl, 6111111 > 2. Kowalski, Jan, CRS, 20567, kowalski@crs.pl, 6578905 > 3. Kowalski, Adam, CRS, 30300, kowalski@cos.pl, 7444444 > > to jako duplikat powinny byc zakwalifikowane rekordy o id 1 i 3 > > Ktos ma pomysl na jakiegos SQL'a?
select a.*, b.id from tab as a, tab as b where ( case when a.lastname = b.lastname then 1 else 0 end + case when a.firstname = b.firstname then 1 else 0 end + .... ) >= 3
Wypisze wszystkie rekordy, które posiadają duplikaty i do których są podobne. Jeśli ta ostatni informacja jest ci nie potrzebna, to użyj distinct lub group by
-- P.M.
Stachu99 - 17-05-2006 00:41
Uzytkownik "pawelcs" <pawelcs@googlemail.com> napisal w wiadomosci news:1147792644.795519.70590@g10g2000cwb.googlegro ups.com... > Witam, > > Mam nastepujacy problem. Potrzebuje znalezc wszytskie duplikaty w > tabeli. Duplikatami sa rekordy w ktorych trzy z pieciu wybranych kolumn > przechowuja takie same wartosci (case insensative). > przyklad: > kolumny brane pod uwage: > lastname, firstname, company, postalcode, email > > i mamy trzy rekordy: > > id, lastname, firstname, company, postalcode, email, phone > 1, Kowalski, Jan, BMX, 30300, kowalski@cos.pl, 6111111 > 2. Kowalski, Jan, CRS, 20567, kowalski@crs.pl, 6578905 > 3. Kowalski, Adam, CRS, 30300, kowalski@cos.pl, 7444444 > > to jako duplikat powinny byc zakwalifikowane rekordy o id 1 i 3 > > Ktos ma pomysl na jakiegos SQL'a? >
Pod Firebirdem dziala. Na pewno sa inne rozwiazania ale te tez dziala choc troszke wolno. Gorzej gdyby bylo wiecej pól do porównywania. Przyklad: Tabela OSOBY2 Id, Nazwisko, Imie1, Plec, Pesel, DowodOsobisty - sprawdza: Nazwisko, Imie1, Plec, Pesel, DowodOsobisty.
SELECT * FROM OSOBY2 A WHERE
(EXISTS (SELECT COUNT(*) FROM OSOBY2 B WHERE A.Nazwisko=B.Nazwisko AND A.Imie1=B.Imie1 AND A.Plec=B.Plec AND B.Nazwisko<>'' AND B.Imie1<>'' AND B.Plec<>'' GROUP BY B.Nazwisko, B.Imie1, B.Plec HAVING COUNT(*)>1))
OR (EXISTS (SELECT COUNT(*) FROM OSOBY2 B WHERE A.Nazwisko=B.Nazwisko AND A.Imie1=B.Imie1 AND A.Pesel=B.Pesel AND B.Nazwisko<>'' AND B.Imie1<>'' AND B.Pesel<>'' GROUP BY B.Nazwisko, B.Imie1, B.Pesel HAVING COUNT(*)>1))
OR (EXISTS (SELECT COUNT(*) FROM OSOBY2 B WHERE A.Nazwisko=B.Nazwisko AND A.Imie1=B.Imie1 AND A.DowodOsobisty=B.DowodOsobisty AND B.Nazwisko<>'' AND B.Imie1<>'' AND B.DowodOsobisty<>'' GROUP BY B.Nazwisko, B.Imie1, B.DowodOsobisty HAVING COUNT(*)>1))
OR (EXISTS (SELECT COUNT(*) FROM OSOBY2 B WHERE A.Imie1=B.Imie1 AND A.Plec=B.Plec AND A.Pesel=B.Pesel AND B.Imie1<>'' AND B.Plec<>'' AND B.Pesel<>'' GROUP BY B.Imie1, B.Plec, B.Pesel HAVING COUNT(*)>1))
OR (EXISTS (SELECT COUNT(*) FROM OSOBY2 B WHERE A.Imie1=B.Imie1 AND A.Plec=B.Plec AND A.DowodOsobisty=B.DowodOsobisty AND B.Imie1<>'' AND B.Plec<>'' AND B.DowodOsobisty<>'' GROUP BY B.Imie1, B.Plec, B.DowodOsobisty HAVING COUNT(*)>1))
OR (EXISTS (SELECT COUNT(*) FROM OSOBY2 B WHERE A.PLEC=B.Plec AND A.Pesel=B.Pesel AND A.DowodOsobisty=B.DowodOsobisty AND B.Plec<>'' AND B.Pesel<>'' AND B.DowodOsobisty<>'' GROUP BY B.Plec, B.Pesel, B.DowodOsobisty HAVING COUNT(*)>1))
ORDER BY A.Nazwisko
Pozdrawim, Stachu99
Pawel M. - 20-05-2006 00:04
Dziekuje wszsytkim za odpowiedz. Ostatnie rozwiazanie wydaje sie dziala. Moze jednak kto zna jakies bardziej efektywne zapytanie ?
Pozdrawiam, Pawel
=?ISO-8859-2?Q?Micha=B3?= Kuratczyk - 20-05-2006 00:04
Pawel M. wrote: > Moze jednak kto zna jakies bardziej efektywne zapytanie ?
Zakładając, że identyczne wartości kolumn a1, a2 i a3 oznaczają duplikat:
SQL> create table foo (a1 number, a2 number, a3 number, a4 number, a5 number);
Table created.
SQL> insert into foo values (1, 2, 3, 4, 5);
1 row created.
SQL> insert into foo values (1, 2, 3, 4, 6);
1 row created.
SQL> insert into foo values (1, 2, 2, 4, 5);
1 row created.
SQL> insert into foo values (1, 2, 2, 4, 6);
1 row created.
SQL> insert into foo values (1, 2, 3, 4, 5);
1 row created.
SQL> insert into foo values (1, 2, 3, 4, 7);
1 row created.
SQL> insert into foo values (1, 3, 3, 4, 5);
1 row created.
SQL> insert into foo values (1, 3, 1, 4, 5);
1 row created.
SQL> select * from foo where (a1, a2, a3) in 2 (select a1, a2, a3 from foo group by a1, a2, a3 having count(*) > 1);
A1 A2 A3 A4 A5 ---------- ---------- ---------- ---------- ---------- 1 2 3 4 5 1 2 3 4 6 1 2 2 4 5 1 2 2 4 6 1 2 3 4 5 1 2 3 4 7
6 rows selected.
-- Michał Kuratczyk
Pawel M. - 20-05-2006 00:04
tak, ale zalozenie jest inne, ze przynajmniej trzy obojetnie jakie kolumny z pieciu ma takie same wartosci to jest to duplikat.
Pawel M. - 20-05-2006 00:04
tak, ale zalozenie jest inne, ze przynajmniej trzy obojetnie jakie kolumny z pieciu ma takie same wartosci to jest to duplikat.
Pozdrawiam, Pawel
=?ISO-8859-2?Q?Micha=B3?= Kuratczyk - 23-05-2006 00:24
Pawel M. wrote: > tak, ale zalozenie jest inne, ze przynajmniej trzy obojetnie jakie > kolumny z pieciu ma takie same wartosci to jest to duplikat. Jeśli wystarczą Ci wartości z kolumn, które się powtarzają, to coś takiego:
select a1,a2,a3,a4,a5 from foo group by grouping sets ( (a1, a2, a3), (a1,a2,a4), (a1,a2,a5), ... ) having count(*) > 1
Jeśli potrzebujesz całych rekordów, to musiałbyś to wykorzystać jako podzapytanie. Ogólnie obawiam się, że z wydajnością będzie kiepsko w każdym wypadku. Najlepsze co mi przychodzi do głowy, ale ograniczone w swoich zastosowaniach, byłoby założenie odpowiedniej ilości constraintów (na wszystkie kombinacje trzech z pięciu kolumn) i klauzula EXCEPTIONS INTO <tabela>, żeby Oracle sam Ci wrzucił do tej tabeli ROWID wierszy, które naruszają constrainty.
-- Michał Kuratczyk
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
Oracle, SQL, PL/SQL. Jak =?ISO-8859-2?Q?napisa=E6_zapytanie=2C?==?ISO-8859-2?Q?_kt=F3re_zwr=F3ci_nazw=EA_atrybutu=2C_kt=F3reg o?==?ISO-8859-2?Q?_warto=B6ci_spe=B3niaj=B1_zadany_warunek?=
Oracle 19g +Insert +Insert +Insert...
[oracle] zapytanie dynamiczne z =?ISO-8859-2?Q?=22dynamiczn=B1_?==?ISO-8859-2?Q?nazw=B1_tabeli=22?=
[Oracle] jak =?ISO-8859-2?Q?ograniczy=E6_pami=EA=E6_dla_se?==?ISO-8859-2?Q?rwera=3F?=
=?ISO-8859-2?Q?=5BOT=5D_Zdany_egzamin_Oracle_1Z0-007_a?==?ISO-8859-2?Q?_brak_informacji_na_stronie_Prometric_-_czy?==?ISO-8859-2?Q?_co=B6_nie_tak=3F?=
[oracle] czy da =?ISO-8859-2?Q?si=EA_z_poziomu_procedury_?==?ISO-8859-2?Q?zrobi=E6_kopi=EA_zapasow=B1=3F?=
[oracle 10g] czy =?ISO-8859-2?Q?mo=BFna_wy=B3=B1czy=E6_wszys?==?ISO-8859-2?Q?tkie_wi=EAzy_w_schemacie=3F?=
MSSQL Express czy Oracle Express
=?iso-8859-2?q?[oracle]_Jak_sprawdzi=E6_wielko=B6=E6_tabeli_=3F=3F?=
=?ISO-8859-2?Q?Poszukjue_ksi=B1=BFki_"Oracle_?= =?ISO-8859-2?Q?optymalizacja_wydajno=B6ci"..?=
zanotowane.pldoc.pisz.plpdf.pisz.planette.xlx.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|