Verificare si modificare valori duplicate in MySQL

Discutii despre script-uri si coduri PHP-MySQL, precum si lucru cu XML in PHP.
ciprian2301
Mesaje: 9

Verificare si modificare valori duplicate in MySQL

Salutare,
Am urmatorul script pt importul de csv.

Cod: Selectaţi tot

 if($request->get($_POST["action"]) == "import"){
       $file = $upload->file_upload("import", "media/import");
       if(file_exists(DIR_UPLOAD_PHOTO . "/media/import/" . $file)){
          
             $file = DIR_UPLOAD_PHOTO . "/media/import/" . $file;
             $handle = fopen($file, "r");
         
         if ($handle) {
             $lines = explode("\r", fread($handle, filesize($file)));
         } 
         
         $total_array = count($array);
         
         $x = 0;

         foreach($lines as $line){
            if($x >= 1){
                $data = explode("|", $line);
                
                $titlu          = trim(addslashes($data[0]));
                $alias          = $this->generate_seo_link($titlu);
               $gramaj       = trim($data[1]);
               $greutate       = trim($data[2]);
               $pret_total    = trim($data[3]);
               $pret_redus    = trim($data[4]);
               $poza          = trim($data[5]);
               $pret_unitar    = trim($data[6]);
               $categorie       = trim($data[7]);
               $brand          = trim(addslashes($data[8]));
               $descriere       = trim(addslashes($data[9]));
               $vizibil       = trim($data[10]);
               $cod          = trim($data[11]);
               $nou          = trim($data[12]);
               $cant_variabila = trim($data[13]);
               $congelat       = trim($data[14]);
               $tva         = trim($data[15]);
               $stoc         = trim($data[16]);

               
               if($cod != "" && $cod != " "){
                  $database->insert(sprintf("insert into produse set
                                       titlu='%s',
                                       alias='%s',
                                       gramaj='%s',
                                       greutate='%s',
                                       prettotal='%s',
                                       pretredus='%s',
                                       poza='%s',
                                       pretunitar='%s',
                                       categorie='%d',
                                       brand='%s',
                                       descriere='%s',
                                       vizibil='%d',
                                       cod='%s',
                                       nou='%d',
                                       cant_variabila='%d',
                                       congelat = '%d',
                                       tva = '%s',
                                       stoc = '%d'
                                       
                                       on duplicate key update
                                       
                                       titlu='%s',
                                       alias='%s',
                                       gramaj='%s',
                                       greutate='%s',
                                       prettotal='%s',
                                       pretredus='%s',
                                       poza='%s',
                                       pretunitar='%s',
                                       categorie='%d',
                                       brand='%s',
                                       descriere='%s',
                                       vizibil='%d',
                                       cod='%s',
                                       nou='%d',
                                       cant_variabila='%d',
                                       congelat = '%d',
                                       tva='%s',
                                       stoc= '%d'",
                                       $titlu, $alias,
                                       $gramaj, $greutate, $pret_total, $pret_redus, $poza, $pret_unitar, $categorie,
                                       $brand, $descriere, $vizibil, $cod, $nou, $cant_variabila, $congelat,
                                       $tva, $stoc,

                                       $titlu, $alias, $gramaj, $greutate,
                                       $pret_total, $pret_redus, $poza, $pret_unitar, $categorie, $brand, $descriere,
                                       $vizibil, $cod, $nou, $cant_variabila, $congelat, $tva, $stoc));   
                  
                              
                                                                   
               }
            }   
             $x++;
         } 
          
             
          
       }
    }
Vreau sa verific mai intai daca am alias duplicat in bd, apoi sa incrementez valorile duplicate cu 1 folosind functia increment_string postata mai jos, apoi sa fac insert sau update dupa caz.
Cum as putea proceda in asa fel incat sa nu am valori duplicate pentru alias ?
Tin sa precizez ca folosesc coloana alias pt seo si trebuie sa aibe valori diferite.

Cod: Selectaţi tot

 function increment_string($str, $separator = '-', $first = 1){
      preg_match('/(.+)'.$separator.'([0-9]+)$/', $str, $match);

      return isset($match[2]) ? $match[1].$separator.($match[2] + 1) : $str.$separator.$first;
  }

MarPlo Mesaje: 4343
Salut
Daca vrei sa afli valorile duplicate dintr-o anumita coloana din tabel mysql, poti folosi unul din aceste doua select-uri; returneaza id-urile si valorile duplicate.

Cod: Selectaţi tot

SELECT id, alias FROM produse
WHERE alias IN (
    SELECT alias FROM produse
    GROUP BY alias
    HAVING COUNT(id) > 1
)
Sau

Cod: Selectaţi tot

select id, alias, count(*) as Count from produse
group by alias
having count(*) > 1
Apoi se parcurg datele returnate si retii id-urile intr-un sir separate prin virgula, iar ca sa nu mai fie duplicate, se face update la acele id-uri, adaugand la alias propriul id.

Exemplu:

Cod: Selectaţi tot

$sql = "SELECT id, alias FROM produse WHERE alias IN (
    SELECT alias FROM produse GROUP BY alias HAVING COUNT(id) > 1
)";
// executie query ...

$ids = array();
while(...) {
  $ids[] = $row['id'];
}

$sql = "UPDATE produse SET alias = concat(alias, '_', id) WHERE id IN(". implode(',', $ids) .")";
// ... 

ciprian2301 Mesaje: 9
Am ajuns la urmatorul SQL query, care imi identifica valorile duplicate si le numeroteaza apoi imi incrementeaza in coloana "num" valoarea lui alias+nr :

Cod: Selectaţi tot

select alias, titlu, group_row_number, 
  concat(alias, cast(group_row_number as char)) as num,
  overall_row_num
from
(
  select alias, titlu,
        @num := if(@alias = `alias`, @num + 1,'' ) as group_row_number,
        @alias := `alias` as dummy, overall_row_num
  from
  (
    select alias, titlu, @rn:=@rn+1 overall_row_num
    from produse, (SELECT @rn:=0) r
  ) x
  order by alias, overall_row_num
) x
order by overall_row_num
- Acum nu stiu cum as putea face insert-ul.

MarPlo Mesaje: 4343
Depinde ce date obtii din acel Select, structura returnata, si ce Insert vrei sa faci. Sa le mai adaugi inca o data sau Update?
Poate iti functiona direct varianta postata aterior.

ciprian2301 Mesaje: 9
Query-ul postat mai sus imi returneaza

Cod: Selectaţi tot

Array
(
    [alias] => Array
        (
            [0] => coca-cola-light-la-doza
            [1] => hdr-cutie-depozitare-cu-capac-80-l
            [2] => homemarket-cos-mic-cadou
            [3] => kuhne-ceapa-argintie
            [4] => kuhne-ceapa-argintie
            [5] => kuhne-ceapa-argintie
            [6] => kuhne-ceapa-argintie
            [7] => lumanari-pastila-120buc
            [8] => natura-verde-miez-de-dovleac-neprajit
        )

    [titlu] => Array
        (
            [0] => COCA COLA LIGHT LA DOZA
            [1] => HDR CUTIE DEPOZITARE CU CAPAC 80 L
            [2] => HOMEMARKET COS MIC CADOU
            [3] => KUHNE CEAPA ARGINTIE
            [4] => KUHNE CEAPA ARGINTIE
            [5] => KUHNE CEAPA ARGINTIE
            [6] => KUHNE CEAPA ARGINTIE
            [7] => LUMANARI PASTILA 120BUC
            [8] => NATURA VERDE MIEZ DE DOVLEAC NEPRAJIT
        )

    [group_row_number] => Array
        (
            [0] => 
            [1] => 
            [2] => 
            [3] => 
            [4] => 1
            [5] => 2
            [6] => 3
            [7] => 
            [8] => 
        )

    [num] => Array
        (
            [0] => coca-cola-light-la-doza
            [1] => hdr-cutie-depozitare-cu-capac-80-l
            [2] => homemarket-cos-mic-cadou
            [3] => kuhne-ceapa-argintie
            [4] => kuhne-ceapa-argintie1
            [5] => kuhne-ceapa-argintie2
            [6] => kuhne-ceapa-argintie3
            [7] => lumanari-pastila-120buc
            [8] => natura-verde-miez-de-dovleac-neprajit
        )

)
Ma intereseaza sa fac insert doar pt array num.

MarPlo Mesaje: 4343
Nu e rezolvare sa faci insert la o singura coloana, findca la insert datele se adauga pe randuri, si raman celelalte coloane de pe randurile adaugate fara date.
Poate ar trebui Update la coloana "alias" cu valorile obtinute in array-ul "num"; iar in acest caz ar trebui sa adaugi in acel Select sa preia si coloana "id". Apoi parcurgi cu for() array-ul "num" si ii faci update in "alias" la id-ul corespunzator din ordinea parcurgerii.

- Dar daca sunt asa putine randuri de modificat, cel mai simplu e sa le modifici manual direct in PhpMyAdmin.

ciprian2301 Mesaje: 9
Am rezolvat problema in proportie de 80% cu :

Cod: Selectaţi tot

						$verificare = $database->selectn("SELECT alias FROM produse WHERE alias LIKE '%".$alias."%'");	
						foreach ($verificare as $check) {
							if($alias == $check['alias']){
							     $alias = $this->increment_string($alias);
							 }else{
							 	 
								 $alias = $alias;
							}
					    }
Din 32 000 de produse imi returneaza 125 de duplicate.


Edit:
Problema e din cauza functiei increment_string().
In urma selectului imi incrementeaza doar pana la 10.

Subiecte similare