Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: usuwanie zdublowanych rekordów
Forum PHP.pl > Forum > Bazy danych > MySQL
nubian
czy istnieje funkcja pozwalająca usunąć z bazy identyczne rekordy? oczywiście tak aby jeden z nich został.
Seth
Kod
SELECT DISTINCT...
itsme
seth ale czy te polecenie sprawdza rekordy z dwoch roznych tabel
czy sprawdza poszczegolne rekordy z jednej tabeli gdzie wyszczegolniamy kolumny do sprawdzenia questionmark.gif?

pozdrawiam
Seth
troche pospieszylem sie z poprzednim postem. DISTINCT sluzy do wypisywania w SELECTcie rekordow bez ich duplikatow. Ale mysle, ze mozna jakos z tym pokombinowac i usuwac zduplikowane rekordy.

itsme: musze Cie odeslac do www.mysql.com bo tam to bedzie najlepiej wyjasnione
itsme
seth: soryy moj angielski jest skromny sad.gif(((((((( hlip hlip
nubian
Cytat
Kod
SELECT DISTINCT...


to polecenie znam, ale właśnie jak napisałeś Seth ono tylko wyświetla różne rekordy, a problem jest z ich usunięciem, kurde myślałem że jest do tego jakaś funkcja specjalna ale wertuję książkę do sql'a i nic nie ma na ten temat :cry:
talee
Dziś mam dobry humor smile.gif no i trochę czasu, ostatnio słabo sypiam, więc dostaniesz gotowca.
Kod
$DB_HOST = 'questionmark.gif?';

$DB_NAME = 'questionmark.gif?';

$DB_USER = 'questionmark.gif?';

$DB_PASSWD = 'questionmark.gif?';



mysql_connect($DB_HOST, $DB_USER, $DB_PASSWD);

mysql_select_db($DB_NAME);



$table_name = 'test';              // tabela z którą pójdziemy

                                   // na randkę!!!

$tmp_table_name =  uniqid('tmp');



/* chyba wiadomo co wpisać */

$db_table_schema = <<< EOQ

CREATE TABLE $tmp_table_name (

id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,

first_name VARCHAR(50) NOT NULL DEFAULT '',

surname VARCHAR(50) NOT NULL DEFAULT '',

PRIMARY KEY (id)

) TYPE=MyISAM;

EOQ;

/* ? ? ? */



mysql_query($db_table_schema);



$group_by = 'first_name, surname'; // nazwy pól, które nie mają

                                   // mieć identycznych wartości



$db_query = <<< EOQ

INSERT INTO $tmp_table_name

SELECT *

FROM $table_name

GROUP BY $group_by;

EOQ;



mysql_query($db_query);



$db_query = <<< EOQ               // randka się nie udała

DROP TABLE $table_name            // żegnam cię kochanie

EOQ;



mysql_query($db_query);



$db_query = <<< EOQ               // mam sentyment do dziewczyn

ALTER TABLE $tmp_table_name       // o imieniu $table_name

RENAME $table_name;

EOQ;



mysql_query($db_query);



?>


Na przyszłość polecam manual MySQL
msulik
Też mam dobry humor i inne rozwiązanie, nie bazujące na kopiach tabel:
Kod
<?

mysql_pconnect ('adres','user','haslo');

mysql_select_db ('moja_baza');



/*

Niech dana bedzie tabela o nazwie `moja_tabela` o polach `pole_1`, `pole_2`, ..., `pole_n`

*/



/*

Jesli tabela dodatkowo ma klucz podstawowy, to niech nazywa sie on `id`

*/



/*

Jesli tabela nie ma klucza podstawowego, to go dodajmy:

*/

mysql_query ('ALTER TABLE moja_tabela ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY');



/*

Wyszukujemy wszystkie rekordy, ktore posiadaja duplikaty. Beda nam potrzebne ich identyfikatory `id`.

*/



$res = mysql_query ('SELECT mt2.id FROM moja_tabela AS mt1, moja_tabela AS mt2 WHERE mt1.id < mt2.id AND mt1.pole_1 = mt2.pole_1 AND mt1.pole_2 = mt2.pole_2 AND ... AND mt1.pole_n = mt2.pole_n GROUP BY mt2.id');



/*

Znak < w zapytaniu sprawia, ze jeden ze zduplikowanych rekordow (ten o najnizszym id) nie zostanie zwrocony w zapytaniu, dzieki czemu nie usuniemy go.

*/



if ($row = mysql_fetch_array ($res))

{

/*

Tworzymy warunek dla instrukcji DELETE.

Mozna tez wykonac sekwencyjnie kilka instrukcji DELETE dla $row['id'] z kazdego wiersza zwroconego w zapytaniu, ale to zajmuje wiecej czasu niz jedna instrukcja DELETE.

*/

  $war = 'id IN ('.$row['id'];

  while ($row = mysql_fetch_array ($res))

  {

    $war .= ','.$row['id'];

  }

  $war .= ') LIMIT '.mysql_num_rows ($res); /* w wersji MySQL >= 3.22.7 */

/*

Nie przejmujemy sie tym, ze w warunku moga wystapic powtorzenia typu `id IN (5,3,5)`.

*/

  $que = 'DELETE FROM moja_tabela WHERE '.$war;

}



/*

Jesli tabela na poczatku nie miala klucza podstawowego, ktory dodalismy, to mozemy go usunac

*/

mysql_query ('ALTER TABLE moja_tabela DROP id');



?>
itsme
a ja mam cos mniej tresciwego
Kod
<?

function sql($zapytanie)

{

$polaczenie=mysql_connect ("host", "login", "pass");

mysql_select_db("baza");

$result=mysql_query($zapytanie);

return $result;

mysql_close($polaczenie);

}



$numer_rekordu=1;

$pytanie="select pole_ktore_ma_byc_sprawdzane, id from tabela order by pole_ktore_ma_byc_sprawdzane;";

$wynik=sql($pytanie);

while($wiersz = mysql_fetch_row($wynik))

                {

    $pole[$numer_rekordu]=$wiersz[0];

    $id[$numer_rekordu]=$wiersz[1];

    $poprzedni_rekord=$numer_rekordu-1;



    if ($pole[$numer_rekordu]==$pole[$poprzedni_rekord])

  {

  $pytanie2="delete from tabela where `id`='$id[$numer_rekordu]';";

  sql($pytanie2);

  }

    $numer_rekordu++;

    }

?>

oczekuje opinii na moje kombinatorstwo
pozdrawiam
nubian
dziękuję wszystkim mającym dobry humor:) zdaję sobie sprawę że taki skrypt da się napisać ale mi się po prostu nie chce i dlatego szukałem funkcji to robiącej za mnie:)
talee
To jest bardzo brzydki kawałek kodu sad.gif

Kod
<?

function sql($zapytanie)

{

$polaczenie=mysql_connect ("host", "login", "pass");

mysql_select_db("baza");

$result=mysql_query($zapytanie);

return $result;

mysql_close($polaczenie);

}

...

?>

Po pierwsze procedura łączenia z bazą jest bardzo łakoma sad.gif, a ty w tym skrypcie wywołujesz ją ?.? razy. Nagroda dla tego, kto zgadnie ile razy. Po drugie nie rozumiem, po co używasz $polaczenie (znowu oszczędności :!: ).

Kod
<?

$polaczenie=mysql_connect ('host', 'login', 'pass');

mysql_select_db('baza', $polaczenie);



$numer_rekordu=1;

$pytanie='select pole_ktore_ma_byc_sprawdzane, id from tabela order by pole_ktore_ma_byc_sprawdzane;';



// tu możemy pogadać z inną bazą



$wynik=mysql_query($pytanie, $polaczenie);



// tu możemy pogadać z inną bazą



while($wiersz = mysql_fetch_row($wynik))

                {

   $pole[$numer_rekordu]=$wiersz[0];

   $id[$numer_rekordu]=$wiersz[1];

   $poprzedni_rekord=$numer_rekordu-1;



   if ($pole[$numer_rekordu]==$pole[$poprzedni_rekord])

      {

      $pytanie2="delete from tabela where `id`='$id[$numer_rekordu]';";

      mysql_query($pytanie2, $polaczenie);

      }

   $numer_rekordu++;

   }

mysql_close($polaczenie);

?>


Oczywiście w przypadku negocjacji z jedną bazą $polaczenie jest nadmiarowe.

Niestety nie mogę ci powiedzieć czy twój skrypt zadziała poprawnie (mój interpreter nie jest jeszcze na takimi poziomie rozwoju i myślę, że nigdy nie będzie :wink: ), ale znam jedną prawdę życiową: Skrypt php nie powinien robić tego co może zrobić serwer SQL. Cierpię bardzo z powodu braku podzapytań w MySQL'u, ale to chyba nie potrwa długo tongue.gif .

Mam nadzieję, że nie byłem okrutny w mojej krytyce rolleyes.gif i respirator nie będzie potrzebny. Człowiek uczy się na błędach, zazwyczaj swoich :!: :!: :!: .
talee
Cytat
dziękuję wszystkim mającym dobry humor:) zdaję sobie sprawę że taki skrypt da się napisać ale mi się po prostu nie chce i dlatego szukałem funkcji to robiącej za mnie:)


Zdenerwowałem się angrysmiley.gif .

Ludzie się starają tracą czas, a koleś wypisuje takie rzeczy. Może jeszcze byś chciał żeby php zrobiło ci herbatę :idea: .

Jeżeli nadal nie kumasz to taka funkcja istnieje mysql_query('...').

A skryptu nie musisz pisać, szkoda twego trudu. Możesz podpisać się pod którymś powyżej, masz od wyboru do koloru, :!: :!: :!: taki z ciebi [....].

Znalazłeś się na mojej czarnej liście. Pamiętaj ja wyskoczysz z czymś lamerskim to cię zniszczę tongue.gif .
msulik
Wiesz, talee, dałeś mi do myślenia. Nie chciałbym kiedyś spotkać człowieka, który zaprezentowałby mi moje rozwiązanie jako swoje. W zasadzie to ten człowiek wolałby mnie nie spotkać >:o[

Nubian, mi też się nie chce. Już dawno miałbym napisany zagrzebisty sklep, ale mi się nie chce. Jednak to nie znaczy, że proszę kogoś o napisanie go za mnie. Czas ucieka, a ja nie mam co pokazać jako kandydat do pracy. No, może z wyjątkiem kilku - IMO - ciekawych rozwiązań na tym i na innych forach. Dużo czasu straciłem na forach i właśnie stwierdziłem, że mi się też nie chce.

PS. Jakbym powiedział mojemu potencjalnemu pracodawcy, że rozdaję swoje rozwiązania na ulicy, to zażyczyłby sobie ode mnie pracy za darmo.
itsme
Talee: masz racje co do bledow dzieki za poprawki
kazdy ma swoje metody w tym wypadku kod jest czytelny zas usuniecie zdublowanych rekordow to zyczenie admina moze byc za kazdym razem uruchamiane lub o 12:00 kazdego dnia smile.gif)))

Pozdrawiam
borcenty
Cytat(msulik @ 2002-09-14 14:33:27)
Też mam dobry humor i inne rozwiązanie, nie bazujące na kopiach tabel:?>[/CODE]

super, bardzo dobre rozwiazanie. Wprawdzie trwa dlugo (2,13sek na 300 rekordach w tym jeden powtorzony) ale z pktu widzenia wydajnosci to i tak lepsze niz budowanie nowych tabel, kopiowanie, itp.

jestes wielki! smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.