English 中文(简体)
Select duplicates with PHP & MySql for merging process
原标题:

I wrote some code to select duplicates and group them using first and last names. I gather them into a multidimensional array and dedupe/merge them using jQuery/Ajax on the resulting page. I would like to ask if there is a better method of creating the array than how I m doing it. Here is my code. Thank you.

$dataArr=fetchDups($conn, 13, 5); // get a few at a time

print  <div style="clear:both;"></div><pre> ;
print_r($dataArr);
print  </pre><div style="clear:both;"></div> ; 


    function fetchDups($conn, $client_id, $limit=  )
    {

     $sql=  SELECT * FROM `contacts` WHERE `clientid`= 13  GROUP BY fname, lname  ;
     //$sql=  SELECT DISTICT fname, lname, * FROM `clients` WWHERE `clientid`= 13   ;
     $res=mysql_query($sql, $conn)or die(mysql_error());
     $contactsRow=array();
     while($row=mysql_fetch_array($res)){
      echo $row[ fname ]. <br> ;
      $contactsRow[]=$row;
     }

  mysql_freeresult($res);

  $dataArr=array();
  $i=0;  
  $limitNum=0;
  //----------------------------------  

  foreach($contactsRow AS $rowNew){

   $sql=  SELECT * FROM `contacts` WHERE `clientid`= 13  AND `id`!=  .$rowNew[ id ].    
    AND (`fname` =   .$rowNew[ fname ].   OR `lname` =   .$rowNew[ lname ].  )
    ;
   //echo $sql;
   $res=mysql_query($sql, $conn)or die(mysql_error());
   $rowCountDup=mysql_num_rows($res);

   if($rowCountDup>0){

    $d=0;
    $dataArr[$i]=array();
    $dataArr[$i][$d]=$rowNew;
    while($rowNew=mysql_fetch_array($res)){
     $dataArr[$i][($d+1)]=$rowNew;
     $d++;    
    }

    $i++;
    $limitNum++;    

   }

   // limit the results. too many crashes the browser
   if($limitNum==$limit){
    break;
   }   

  }

  mysql_freeresult($res);

  return $dataArr;

    }
最佳回答

For this kind of things, you should probably try using:

SELECT * FROM contacts refC JOIN contacts allC USING (fname, lname) WHERE refC.clientid= 13

This does a self-join on contacts based on first and last name, so allC aliases to the list of all contacts that share refC s first and last names (including himself).

This way, you get all the information you re looking for in only one SQL query. Tuning may be achieved on the query by adding an index on columns fname and lname of table contacts, so the join doesn t have to parse the whole table to match.

--edit: You may get to specify more finely how you join your tables as for instance:

SELECT *
FROM contacts refC
JOIN contacts allC ON (allC.fname LIKE CONCAT(refC.fname,  % ) AND allC.lname LIKE CONCAT(refC.lname,  % ))
WHERE refC.clientid= 13 

Which is strictly equivalent (but IMO easier to read than) to:

SELECT *
FROM contacts refC,contacts allC
WHERE allC.fname LIKE CONCAT(refC.fname,  % ) 
AND allC.lname LIKE CONCAT(refC.lname,  % )
AND refC.clientid= 13 
问题回答

If you just want to avoid displaying duplicates and not actually removing them from your db, use DISTINCT SQL keyword.

Or you could try something like the second query here which uses a derived table:

mysql> select * from contacts ;
+----+--------+---------+
| id | fname  | lname   |
+----+--------+---------+
| 1  | Annie  | Haddock |
| 2  | Annie  | Haddock |
| 3  | Ginger | Mole    |
| 4  | Ted    | Ted     |
| 5  | Ted    | Ted     |
+----+--------+---------+
5 rows in set (0.01 sec)

mysql> select id, fname, lname, total from 
             (select *, count(*) as total 
              from contacts group by fname, lname) people 
       where total > 1;
+-----------+--------------+--------------+--------------+
| people.id | people.fname | people.lname | people.total |
+-----------+--------------+--------------+--------------+
| 1         | Annie        | Haddock      | 2            |
| 4         | Ted          | Ted          | 2            |
+-----------+--------------+--------------+--------------+
2 rows in set (0.01 sec)

then just iterate through it with foreach. Note that "people" above is an alias for the derived table created by the inner select





相关问题
SQL SubQuery getting particular column

I noticed that there were some threads with similar questions, and I did look through them but did not really get a convincing answer. Here s my question: The subquery below returns a Table with 3 ...

please can anyone check this while loop and if condition

<?php $con=mysql_connect("localhost","mts","mts"); if(!con) { die( unable to connect . mysql_error()); } mysql_select_db("mts",$con); /* date_default_timezone_set ("Asia/Calcutta"); $date = ...

php return a specific row from query

Is it possible in php to return a specific row of data from a mysql query? None of the fetch statements that I ve found return a 2 dimensional array to access specific rows. I want to be able to ...

Character Encodings in PHP and MySQL

Our website was developed with a meta tag set to... <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> This works fine for M-dashes and special quotes, etc. However, I ...

Pagination Strategies for Complex (slow) Datasets

What are some of the strategies being used for pagination of data sets that involve complex queries? count(*) takes ~1.5 sec so we don t want to hit the DB for every page view. Currently there are ~...

Averaging a total in mySQL

My table looks like person_id | car_id | miles ------------------------------ 1 | 1 | 100 1 | 2 | 200 2 | 3 | 1000 2 | 4 | 500 I need to ...

热门标签