2014-03-31 79 views
0

我的問題很難在標題中解釋,所以我會顯示數據和目標。 有一個MySQL表結構如下:使用來自相似行(相同「關鍵字」)的值更新行空字段

CREATE TABLE customerProjectData(
    idCustomer INT NOT NULL, 
    idProject INT DEFAULT NULL, 
    comePersons SMALLINT DEFAULT NULL, 
    comePairs SMALLINT DEFAULT NULL, 
    comment VARCHAR(255) DEFAULT NULL, 
    idCity INT DEFAULT NULL, 
    idStreet INT DEFAULT NULL, 
    name VARCHAR(64) DEFAULT NULL, 
    surname VARCHAR(64) DEFAULT NULL, 
    homeNum VARCHAR(10) DEFAULT NULL, 
    postCode CHAR(6) DEFAULT NULL, 
    postCity VARCHAR(64) DEFAULT NULL, 
    cellPhone VARCHAR(12) DEFAULT NULL 
) 

的事情是,有應和也PRIMARY KEY(idCustomer, idProject)定義,它不是。結果有一些副本(具有相同的主鍵)但具有不同的數據。

我可以運行ALTER IGNORE TABLE但數據丟失可能是不可接受和不可預測的。最後,我們決定嘗試填充來自重複值的空字段(如果它們包含數據),然後運行ALTER IGNORE TABLE。更少的數據會以這種方式丟失,並且在這種情況下是可以接受的(它比現在更長時間的觀點更好)。

問題是如何填補每個副本的這些字段。

回答

1

這是一個粗略的嘗試。

首先嚐試找出沒有。具有相同鍵的行。

<?php 
// $link is the database identifier 

$sql = 'SELECT COUNT(*) AS num, * FROM `customerProjectData` GROUP BY `idCustomer`, `idProject` HAVING COUNT(*) > 1 ORDER BY COUNT(*) ASC;'; 
$run = mysql_query($sql, $link); 

$rows = array(); 
if($run && mysql_num_rows($run)) { 
    while(($fetch = mysql_fetch_assoc($run)) !== false) { 
     $rows[] = $fetch; 
    } 
} 
?> 

現在$rows包含有相同的密鑰和多少次這個鍵在表中被重複count所有行的列表。

您可以編寫一個函數,然後迭代count次並查看哪些行具有完整的數據並使用該函數來使用此記錄的數據填充其他記錄。

有點試驗和錯誤。

+0

哈,好的。我試圖在SQL過程中做到這一點:] – Joe

0

我用@ Web的遊牧建議,並沒有類似的東西,但在SQL過程:

DROP PROCEDURE IF EXISTS correctCPD$$ 
CREATE PROCEDURE correctCPD() 
BEGIN 

    DECLARE currentCustomerId INT; 
    DECLARE currentProjectId INT; 
    DECLARE cur_idCustomer INT; 
    DECLARE cur_idProject INT; 
    DECLARE cur_comePersons SMALLINT; 
    DECLARE cur_comePairs SMALLINT; 
    DECLARE cur_comment VARCHAR(255); 
    DECLARE cur_idCity INT; 
    DECLARE cur_idStreet INT; 
    DECLARE cur_name VARCHAR(64); 
    DECLARE cur_surname VARCHAR(64); 
    DECLARE cur_homeNum VARCHAR(10); 
    DECLARE cur_postCode CHAR(6); 
    DECLARE cur_postCity VARCHAR(64); 
    DECLARE cur_cellPhone VARCHAR(12); 

    CREATE TEMPORARY TABLE ids (
     idCustomer INT, 
     idProject INT 
    ) ENGINE = InnoDB; 

    INSERT INTO ids 
     SELECT idCustomer, idProject FROM customerprojectdata group by idCustomer, idProject having count(*) > 1; 

    BLOCK1: BEGIN 
     DECLARE done INT DEFAULT FALSE; 
     DECLARE itemCur CURSOR FOR SELECT idCustomer, idProject FROM ids; 
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; 

     OPEN itemCur; 

     itemCurLoop: LOOP 
      FETCH itemCur INTO currentCustomerId, currentProjectId; 
      IF done THEN 
       LEAVE itemCurLoop; 
      END IF; 

      BLOCK2: BEGIN 
       DECLARE doneIn INT DEFAULT FALSE; 
       DECLARE cpdCur CURSOR FOR SELECT idCustomer, idProject, comePersons, comePairs, comment, idCity, idStreet, name, surname, homeNum, postCode, postCity, cellPhone FROM customerProjectData WHERE idCustomer = currentCustomerId AND idProject = currentProjectId;  
       DECLARE CONTINUE HANDLER FOR NOT FOUND SET doneIn = TRUE; 

       OPEN cpdCur; 
       cpdCurLoop: LOOP 
        FETCH cpdCur INTO 
         cur_idCustomer, cur_idProject, cur_comePersons, cur_comePairs, 
         cur_comment, cur_idCity, cur_idStreet, cur_name, cur_surname, 
         cur_homeNum, cur_postCode, cur_postCity, cur_cellPhone; 
        IF doneIn THEN 
         LEAVE cpdCurLoop; 
        END IF; 

        UPDATE CustomerProjectData SET 
         comePersons = IF((comePersons IS NULL OR comePersons = '') AND cur_comePersons > 0, cur_comePersons, comePersons), 
         comePairs = IF((comePairs IS NULL OR comePairs = '') AND cur_comePairs > 0, cur_comePairs, comePairs), 
         comment = IF((comment IS NULL OR comment = '') AND cur_comment > 0, cur_comment, comment), 
         idCity = IF((idCity IS NULL AND idStreet IS NULL) AND cur_idCity > 0, cur_idCity, idCity), 
         idStreet = IF(((idCity IS NULL OR idCity = cur_idCity) AND idStreet IS NULL) AND cur_idStreet > 0, cur_idStreet, idStreet), 
         name = IF((name IS NULL OR name = '') AND cur_name > 0, cur_name, name), 
         surname = IF((surname IS NULL OR surname = '') AND cur_surname > 0, cur_surname, surname), 
         homeNum = IF((homeNum IS NULL OR homeNum = '') AND cur_homeNum > 0, cur_homeNum, homeNum), 
         postCode = IF((postCode IS NULL OR postCode = '') AND cur_postCode > 0, cur_postCode, postCode), 
         postCity = IF((postCity IS NULL OR postCity = '') AND cur_postCity > 0, cur_postCity, postCity), 
         cellPhone = IF((cellPhone IS NULL OR cellPhone = '') AND cur_cellPhone > 0, cur_cellPhone, cellPhone) 
        WHERE idCustomer = currentCustomerId AND idProject = currentProjectId; 

       END LOOP; 
       CLOSE cpdCur; 
      END BLOCK2; 
     END LOOP; 

     CLOSE itemCur; 

    END BLOCK1; 

    DROP TEMPORARY TABLE ids; 

END$$ 

感謝您的幫助!

相關問題