使用PHP和MySql选择重复项以进行合并过程
我编写了一些代码来选择重复项并使用名字和姓氏对它们进行分组。我将它们收集到一个多维数组中,并在生成的页面上使用jQuery/Ajax对它们进行重复数据消除/合并。我想问一下,是否有比我现在如何创建数组更好的方法。这是我的密码。多谢各位使用PHP和MySql选择重复项以进行合并过程,php,mysql,duplicates,Php,Mysql,Duplicates,我编写了一些代码来选择重复项并使用名字和姓氏对它们进行分组。我将它们收集到一个多维数组中,并在生成的页面上使用jQuery/Ajax对它们进行重复数据消除/合并。我想问一下,是否有比我现在如何创建数组更好的方法。这是我的密码。多谢各位 $dataArr=fetchDups($conn, 13, 5); // get a few at a time print '<div style="clear:both;"></div><pre>'; print_r($d
$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;
}
如果您只是想避免显示重复项,而不是从数据库中实际删除它们,请使用SQL关键字。对于此类情况,您可能应该尝试使用: 选择*FROM contacts refC JOIN contacts allC USING fname,lname WHERE refC.clientid='13' 这会基于姓名和姓氏对联系人进行自联接,因此所有C别名都会添加到共享refC姓名和姓氏(包括他自己)的所有联系人列表中 这样,您只需在一个SQL查询中获得所需的所有信息。可以通过在表contacts的fname和lname列上添加索引来对查询进行调优,这样连接就不必解析整个表来进行匹配 -编辑:您可以更精细地指定如何联接表,例如:
SELECT *
FROM contacts refC,contacts allC
WHERE allC.fname LIKE CONCAT(refC.fname, '%')
AND allC.lname LIKE CONCAT(refC.lname, '%')
AND refC.clientid='13'
这是严格等效的,但IMO比以下内容更易于阅读:
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)
或者,您可以尝试类似于此处使用派生表的第二个查询:
然后用foreach遍历它。请注意,上面的人是由内部select创建的派生表的别名,他刚刚注意到查询在那里,但他已将其注释掉。您能澄清一下您实际要做的事情吗?我正在尝试获取联系人组,这些联系人组看起来可能重复到一个数组中。我将第二个查询改为使用LIKE,但我仍然不确定这是最好还是最快的方法。可能有300000或更多的记录需要检查。clientid=\'13\'和id!=\$rowNew['id'].\'.$addQuery.'和类似\'%'的fname。addslashes$rowNew['fname'.%\'和类似\'%'的lname。addslashes$rowNew['lname'.%\'忘了提到。。。有很多原因不建议选择*,我最喜欢的是,它会导致应用程序逻辑和数据库结构之间的过度耦合。列的顺序对于代码来说很重要,而不应该如此。@Romain:列的顺序对于代码来说很重要。。。真正地当然,只有在编写代码时依赖顺序。无论是作为关联数组还是对象获取,顺序都不是这里或那里。Select*是坏的,只是因为它可能检索不需要的数据,我同意。但是如果你把自己放在一个DBA的头上,或者期望你的查询被其他人重用,你可能会认为这些人可能对GPP不那么虔诚:在我的情况下,我需要所有的数据,因为当我把页面上的数据显示为重复的组时,我使用一些Jquery/Ajax来允许用户从每个联系人中选择他们想要保留的数据,创建一个包含所有正确信息的新联系人,并将其保存为新联系人,然后删除所有其他DUP。另外,我需要搜索的一些数据是地址和电话。我需要像%一样使用,因为有些人可能会键入稍有不同的内容。我调整了我的答案以满足您的需要。您可以更改ON子句以适合您认为合适的任何匹配。
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)