2012-09-10 91 views
1

我有兩個表 - 「事件」和「房間」。在mysql中用兩條語句更新兩個表

客房表看起來像這樣:

CREATE TABLE `rooms` (
    `roomKey` INT(9) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `locationID` INT(9) NOT NULL DEFAULT '0', 
    `locationName` VARCHAR(150) NOT NULL DEFAULT '', 
    `buildingID` INT(9) NOT NULL DEFAULT '0', 
    `buildingName` VARCHAR(150) NOT NULL DEFAULT '', 
    `areaID` INT(9) NOT NULL DEFAULT '0', 
    `areaName` VARCHAR(150) NOT NULL DEFAULT '', 
    `roomID` INT(9) NOT NULL DEFAULT '0', 
    `roomName` VARCHAR(150) NOT NULL DEFAULT '', 
    `clientKey` MEDIUMINT(5) UNSIGNED NOT NULL DEFAULT '0', 
    PRIMARY KEY (`roomKey`), 
    UNIQUE INDEX `locationID` (`locationID`, `buildingID`, `areaID`, `roomID`, `clientKey`), 
    INDEX `clientKey` (`clientKey`) 

) 
COLLATE='latin1_swedish_ci' 
ENGINE=InnoDB 
AUTO_INCREMENT=21270411; 

和事件表看起來是這樣的:

CREATE TABLE `events` (
    `eventKey` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `accountNum` INT(11) NULL DEFAULT NULL, 
    `locationID` INT(9) NOT NULL DEFAULT '0', 
    `buildingID` INT(9) NOT NULL DEFAULT '0', 
    `areaID` INT(9) NOT NULL DEFAULT '0', 
    `roomID` INT(9) NOT NULL DEFAULT '0', 
    `clientKey` SMALLINT(5) UNSIGNED NOT NULL, 
    `roomKey` INT(10) UNSIGNED NOT NULL DEFAULT '0', 
    `eventTitle` VARCHAR(100) NOT NULL DEFAULT '', 
    `dateStart` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `dateEnd` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `status` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0', 
    PRIMARY KEY (`eventKey`), 
    UNIQUE INDEX `uniqueEvent` (`accountNum`, `locationID`, `buildingID`, `areaID`, `roomID`), 
    INDEX `clientKey` (`clientKey`) 
) 
COLLATE='latin1_swedish_ci' 
ENGINE=InnoDB 
AUTO_INCREMENT=98690419; 

有這將插入新事件到事件表批量導入的過程。完成後,我們需要使用與「房間」表中的主鍵相對應的roomKey更新新記錄 - 我們可以使用房間中的記錄的位置ID,建築ID,區域ID,客房ID和客戶端密鑰進行匹配表。 (clientKey是必要的,因爲多個賬戶可以具有相同的位置,房間,區域或房間值)。

目前,我用這個查詢是:

UPDATE events e, rooms dr SET e.locationKey=dr.locationKey 
     WHERE e.locationID=dr.locationID 
      AND e.buildingID=dr.buildingID 
      AND e.areaID=dr.areaID 
      AND e.roomID=dr.roomID 
      AND e.clientKey=dr.clientKey 

但是當兩個賬戶(客戶端)在位置,大廈,面積和房間相同的值它並沒有考慮到的情況。該查詢容易將錯誤的roomKey值放入事件記錄中,這是基於另一帳戶具有具有相同位置ID,建築ID,區域ID和房間ID的房間記錄的事實。

我可以修改查詢來運行,如下所示,但它非常緩慢。我知道這是不使用正確的查詢,所以我期待,以改善它 - 而不必爲此更新了PHP循環等

UPDATE EVENTS e, rooms dr SET e.locationKey=dr.locationKey 
WHERE (e.locationID=dr.locationID AND e.clientKey=dr.clientKey) 
    AND (e.buildingID=dr.buildingID AND e.clientKey=dr.clientKey) 
    AND (e.areaID=dr.areaID AND e.clientKey=dr.clientKey) 
    AND (e.roomID=dr.roomID AND e.clientKey=dr.clientKey) 
    AND e.clientKey=dr.clientKey 
+0

爲什麼要在兩個表中複製locationID,buildingID,areaID,roomID和clientKey?看起來你可能會很好地看待規範化你的表結構。 –

+0

有效的點,但不幸的是在這一點上不可能重新架構模式。我正在處理日落路上的遺留代碼。現在只需要修復現有設計中的錯誤。 –

+0

因此,房間表中的clientKey值是權威的,您只需要匹配事件中的clientKey值以匹配基於roomID的房間表中的值? –

回答

0

在MySQL中,你可以在update加入時使用此語法

UPDATE table1 t1 
     INNER JOIN table2 t2 
     ON t1.id = t2.id 
SET t1.col1 = t2.col2, t1.col2 = t2.col2 
0

如果roomsclientKey值authoratative,你只是想更新基於匹配roomIDevents所有clientKey值,那麼你應該能夠做到這一點:

UPDATE rooms AS r 
INNER JOIN events AS e ON r.roomKey = e.roomKey 
SET e.clientKey = r.clientKey 
+0

更新爲反映使用'roomKey'作爲連接字段而非'roomID' –