2011-09-01 45 views
0

我正在学习PHP和Zend Framework。下面的PHP函数应该使用“INSERT INTO ... SELECT”样式查询来填充临时表。但是,当我从新附加的表中选择*时,我发现大多数但并非全部的新记录都被复制过一次。每次运行这些脚本时,我都删除了表中的内容。任何人都知道为什么会有重复?来自SELECT的SQL INSERT生成重复记录

public function fillTableByOfficeName($officeName) { 
    if ($officeName != '') { 
     $officePhrase = "b.oof_name ='" . $officeName . "' AND "; 
    } else { 
     $officePhrase = ''; 
    } 

    $whereAddenda = $officePhrase . 
      "a.fil_bool_will_file_online = false AND " . 
      "a.fil_bool_confirmed = false AND " . 
      "a.fil_bool_duplicate = false AND " . 
      "a.fil_bool_not_found = false AND " . 
      "(a.fil_res_id_fk NOT IN (4,7,10) OR a.fil_res_id_fk IS NULL) AND " . 
      "a.fil_will_recorder_rec_id IS NULL AND " . 
      "d.tag_description NOT IN (
       'Already a trust client', 
       'Not received from local office', 
       'Southtrust client (already centralized)')"; 
      //"a.fil_date_of_transfer_to_will_recorder IS NULL"; 

    $sql = "INSERT INTO adds(fil_id,REC_ID,FIRST_NAME,LAST_NAME,MIDDLE_INITIAL,SSN," . 
      "MAILING_ADDRESS_1,MAILING_ADDRESS_2,CITY,STATE,ZIP_CODE,PHONE_NUMBER,BIRTH_DATE," . 
      "ORIGINATION_OFFICE,FILE_LOCATION,WILL_DATE,LAST_CODICIL_DATE,TRUST_DATE,REV_TRUST,POA_DATE) " . 
      "SELECT a.fil_id_pk, " . 
       "a.fil_will_recorder_rec_id, " . 
       "a.fil_first_name, " . 
       "a.fil_last_name, " . 
       "a.fil_middle_name, " . 
       "a.fil_ssn, " . 
       "a.fil_mailing_address_1, " . 
       "a.fil_mailing_address_2, " . 
       "a.fil_city_address, " . 
       "a.fil_state_address, " . 
       "a.fil_zip_code_fk, " . 
       "a.fil_phone_number, " . 
       "a.fil_date_of_birth, " . 
       "b.oof_name, " . 
       "a.fil_box_id_fk, " . 
       "a.fil_date_of_will, " . 
       "a.fil_date_of_last_codicil, " . 
       "a.fil_date_of_trust, " . 
       "a.fil_notes, " . 
       "a.fil_date_of_poa " . 
      "FROM files a, origination_offices b, nn_files_tags c, tags d " . 
      "WHERE " . 
       "a.fil_oof_id_fk = b.oof_id_pk AND " . 
       "a.fil_id_pk = c.fil_id_fk AND " . 
       "d.tag_id_pk = c.tag_id_fk AND " . 
       $whereAddenda; 
    $this->getAdapter()->query($sql); 
    return $this; 
} 
+0

您能否为我们提供数据库转储(无数据,只是创建语句)为表(文件,origination_offices,nn_files_tags,标签)? – dmirkitanov

回答

0

您正在使用C进行多对多关系。例如,如果您有公司和客户之间的发票,并且您选择了它们的联合,那么您将获得与发票一样多的行。因此,如果您只选择公司名称和客户名称,则会有很多重复项目,因为同一个对已经生成了许多发票。

这是你在这里的问题。

正如asc99c所说,您可以使用内部选择使您的WHERE子句不加入该关系,或者您可以使用DISTINCT关键字(实际上是SELECT子句中的所有内容)。我会认为INNER SELECT解决方案更有效率(但我可能完全错误),但DISTINCT的方式是8键按下...

1

您加入表格的方式将为您提供表格中行的笛卡尔乘积(返回所有匹配行对)。

由于没有特定的域名知识,我会猜测标签表格 - 如果您有特定文件的多个标签,您将在结果集中获得该文件的多个副本(每个匹配标签一个)。

由于您不在结果集中使用标记字段,只需要where子句,解决方案就是从主查询中去掉tags/nn_files_tags,并在where子句中使用NOT EXISTS来检查匹配标签表中的行,如下所示:

AND NOT EXISTS (SELECT tag_id_pk FROM tags WHERE tags.tag_id_pk ...