2011-04-26 3 views
0

약 150 만 개의 회사 레코드 (이름, 국가 및 기타 작은 텍스트 필드)가있는 mysql 데이터베이스가 있습니다. 동일한 레코드를 플래그로 표시하려고합니다 (예 : 같은 이름의 두 회사가 미국 그러면 필드 (match_id)를 정수 10과 같게 설정해야하며 다른 일치 항목에 대해서도 마찬가지로 설정해야합니다. 그 순간에 오랜 시간 (일) 복용 내가 제대로 내 자신의 코드를 게시 오전 MySQL을 활용하지 오전 느낌이 빠른 방법이 있나요 ???MYSQL 텍스트 필드 일치

<?php 

//Create the table if does not already exist 
mysql_query("CREATE TABLE IF NOT EXISTS proj ( 
    id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY , 
    company_id text NOT NULL , 
    company_name varchar(40) NOT NULL , 
    company_name_text varchar(33) NOT NULL, 
    company_name_metaphone varchar(19) NOT NULL, 
    country varchar(20) NOT NULL , 
    file_id int(2) NOT NULL , 
    thompson_id varchar(11) NOT NULL , 
    match_no int(7) NOT NULL , 
    INDEX(company_name_text))") 
    or die ("Couldn't create the table: " . mysql_error()); 


//********Real script starts******** 
$countries_searched = array(); //To save record ids already flagged (save time) 
$counter = 1; //Flag 

//Since the company_names which are same are going to be from the same country so I get all the countries first in the below query and then in the next get all the companies in that country 
$sql = "SELECT DISTINCT country FROM proj WHERE country='Canada'"; 
$result = mysql_query($sql) or die(mysql_error()); 

while($resultrow = mysql_fetch_assoc($result)) { 
    $country = $resultrow['country']; 
    $res = mysql_query("SELECT company_name_metaphone, id, company_name_text 
    FROM proj 
    WHERE country='$country' 
    ORDER BY id") or die (mysql_error()); 


    //Loop through the company records 
    while ($row = mysql_fetch_array($res, MYSQL_NUM)) { 

    //If record id is already flagged (matched and saved in the countries searched  array) don't waste time doing anything  
    if (in_array($row[1], $countries_searched)) { 
     continue; 
    } 

    if (strlen($row[0]) > 9) { 
     $row[0] = substr($row[0],0,9); 
     $query = mysql_query("SELECT id FROM proj 
     WHERE country='$country' 
     AND company_name_metaphone LIKE '$row[0]%' 
     AND id<>'$row[1]'") or die (mysql_error()); 

     while ($id = mysql_fetch_array($query, MYSQL_NUM)) { 
     if (!in_array($id[0], $countries_searched)) $countries_searched[] = $id[0]; 
     } 
     if(mysql_num_rows($query) > 0) { 

     mysql_query("UPDATE proj SET match_no='$counter' 
        WHERE country='$country' 
        AND company_name_metaphone LIKE '$row[0]%'") 
      or die (mysql_error()." ".mysql_errno()); 
     $counter++; 
     } 
    } 
    else if(strlen($row[0]) > 3) { 
     $query = mysql_query("SELECT id FROM proj WHERE country='$country' 
       AND company_name_text='$row[2]' AND id<>'$row[1]'") 
     or die (mysql_error()); 
     while ($id = mysql_fetch_array($query, MYSQL_NUM)) { 
     if (!in_array($id[0], $countries_searched)) $countries_searched[] = $id[0]; 
     } 
     if(mysql_num_rows($query) > 0) { 
     mysql_query("UPDATE proj SET match_no='$counter' 
        WHERE country='$country' 
        AND company_name_text='$row[2]'") or die (mysql_error()); 
     $counter++; 
     } 
    } 
    } 
} 
?> 
+0

코드 서식을 수정하십시오. 그 모습은 나를 위해 부러졌다. – jsw

+1

당신이 정말로 이루고자하는 것은 무엇입니까? 요구 사항은 무엇입니까? 코드에 대해 많은 문제점을 볼 수 있지만 요구 사항을 알지 못하면 어떤 방향으로 가리킬 지 확신 할 수 없습니다. 예를 들어 첫 번째 while 루프는 무의미합니다. 당신은 단순히 당신의 기록을 폐지하려고합니까? 또는 동일한 INT로 일치하는 모든 레코드에 플래그를 지정하면됩니까? 당신의 최종 목표는 무엇입니까? –

+0

예 플래그가 같은 int를 가진 레코드와 일치합니다. – nikhil

답변

1

나는 순수한 SQL 솔루션과 같은 것을 갈 것이다 :

SELECT 
    GROUP_CONCAT(id SEPARATOR ' '), "name" 
FROM proj 
WHERE 
    LENGTH(company_name_metaphone) < 9 AND 
    LENGTH(company_name_metaphone) > 3 
GROUP BY country, UPPER(company_name_text) 
HAVING COUNT(*) > 1 
UNION 
SELECT 
    GROUP_CONCAT(id SEPARATOR ' '), "metaphone" 
FROM proj 
WHERE 
    LENGTH(company_name_metaphone) > 9 
GROUP BY country, LEFT(company_name_metaphone, 9) 
HAVING COUNT(*) > 1 

이 결과를 통해 ID를 업데이트하십시오.

+0

감사합니다. – nikhil

0

나는 당신이 일을하려고,하지만 난 당신의 코드에서 볼 수있는 것은, 나는 당신의 문제가 당신을 생각하면 많은 양의 데이터와 배열에 검색을 많이 만들고 있다는 것입니다 무엇 확실하지 않다 PHP 코드 및 SQL 문이 아닙니다.

+0

예,하지만 그 일은 저에게 시간을 절약 해줍니다. – nikhil

0

밖으로 스크립트 시간의 경우,하고 set_time_limit (매우 가능성으로 인해 많은 양의 데이터에)

(0) 그렇지 않으면 당신은 또한을 추가 할 수 있습니다 당신이 일치하는 요구 사항에 맞게 필드를 기준으로 그룹을 조정해야합니다 1000 개 또는 그 이상의 값을 $ sql에 추가하고 where 절이 이미 처리 된 일치하는 행을 제외 할 때 스크립트를 여러 번 실행합니다 (그러나 $ match_no inbetween 호출을 추적하지 않으므로 처리 할 필요가 있습니다)

// find all companies that have multiple rows grouped by identifying fields 

$sql = "select company_name, country, COUNT(*) as num_matches from proj 
where match_no = 0 
group by company_name, country 
having num_matches > 1"; 

$res = mysql_query($sql); 

$match_no = 1; 

// loop through all duplicate companies, and set match_id 
while ($row = mysql_fetch_assoc($res)) { 

    $company_name = mysql_escape_string($row['company_name']); 
    $country = mysql_escape_string($row['country']); 

    $sql = "update proj set match_no = $match_no where 
     company_name = '$company_name', country = '$country'; 

    mysql_query($sql); 

    $match_no++; 
}