2012-05-24 40 views
0

我想在表(如下所示)獲取新插入時自動刪除行,如果滿足某些條件的話。在某些情況下使用mysql刪除行

當:

  • 有指同一個「場」以同樣「USER_ID」
  • 他們的「場」,「顯示」和「搜索」列屬於同一

簡單地說,當行重複時('group_id'列除外)應該刪除非空'group_id',否則應該更新或插入一行。

有沒有辦法在mysql中設置此(在精神「上的重複做的東西」配合獨有的按鍵等),還是我在PHP中明確地檢查它(與多個查詢) ?

附加信息: 對於每個可能的「字段」(其中有一個有限的集合,在其他地方定義),應始終存在一行具有NULL'group_id'的行。另一方面,可能沒有非空'group_id'。

CREATE TABLE `Views` (
`user_id` SMALLINT(5) UNSIGNED NOT NULL, 
`db` ENUM('db_a','db_b') NOT NULL COLLATE 'utf8_swedish_ci', 
`field` VARCHAR(40) NOT NULL COLLATE 'utf8_swedish_ci', 
`display` TINYINT(1) UNSIGNED NOT NULL, 
`search` TINYINT(1) UNSIGNED NOT NULL, 
`group_id` SMALLINT(6) UNSIGNED NULL DEFAULT NULL, 
UNIQUE INDEX `user_id` (`field`, `db`, `user_id`), 
INDEX `Views_ibfk_1` (`user_id`), 
INDEX `group_id` (`group_id`), 
CONSTRAINT `Views_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `User` (`id`) ON 
UPDATE CASCADE ON DELETE CASCADE 
) 
COLLATE='utf8_swedish_ci' 
ENGINE=InnoDB; 
+0

你能否更好地解釋一下:「當除group_id列之外的所有列都相同時,應該刪除非空group_id的行」? – inigomedina

回答

2

我認爲你需要修改你的邏輯。插入一行僅用於刪除另一行是沒有意義的。爲什麼不直接將重複行中的Group_ID字段更新爲正在插入的內容?下面是我如何去做的一個大概的想法。

N.b.我沒有用MySQL做很多工作,並且無法在SQLFiddle上運行以下代碼,但基於MySQL docs我找不到原因。也許有人更熟悉MySQL可以糾正我?

SET @User_ID = 1; 
SET @db = 'db_a'; 
SET @Field = 'Field'; 
SET @Display = 1; 
SET @Search = 1; 
SET @Group_ID = 1; 

IF EXISTS 
    ( SELECT 1 
     FROM Views 
     WHERE User_ID = @User_ID 
     AND  DB = @DB 
     AND  Field = @Field 
     AND  Group_ID IS NOT NULL 
    ) 
    THEN 
     UPDATE Views 
     SET  Group_ID = @Group_ID, 
       Display = @Display, 
       Search = @Search 
     WHERE User_ID = @User_ID 
     AND  DB = @DB 
     AND  Field = @Field 
     AND  Group_ID IS NOT NULL 
ELSE 
     INSERT INTO Views (User_ID, DB, Field, Display, Search, Group_ID) 
     VALUES (@User_ID, @DB, @Field, @Display, @Search, @Group_ID) 
END IF; 

或者(和我的首選解決方案),一個時間戳字段添加到您的表,並創建一個視圖如下:

SELECT v.User_ID, v.DB, v.Field, v.Display, v.Search, v.Group_ID 
FROM Views v 
     INNER JOIN 
     ( SELECT User_ID, DB, Field, MAX(CreatedDate) AS CreatedDate 
      FROM Views 
      WHERE Group_ID IS NOT NULL 
      GROUP BY User_ID, DB, Field 
     ) MaxView 
      ON MaxView.User_ID = v.User_ID 
      AND MaxView.DB = v.DB 
      AND MaxView.Field = v.Field 
      AND MaxView.CreatedDate = v.CreatedDate 
WHERE v.Group_ID IS NOT NULL 
UNION ALL 
SELECT v.User_ID, v.DB, v.Field, v.Display, v.Search, v.Group_ID 
FROM Views v 
WHERE v.Group_ID IS NULL 

這將使你正確跟蹤更改的數據,而不損害了能夠查看唯一記錄的需要。

+0

這不起作用,因爲每個可能的'field'都會有一個NULL的group_id。可以這樣想: 具有空'group_id'的行是每個'字段'的「默認」設置(設置實際上是'字段','顯示'和'搜索'列)。具有group_id(如果存在)的集合然後應用於相應組的默認設置。 我正在處理的代碼已被繼承,並且我試圖在ontop上粘合一個功能,所以我所尋找的是一個很好的折衷方案,它的設置有多簡單,它有多少意義。如果這是有道理的。 – schme

+0

對不起,我編輯了我的答案,我忘了在第一個解決方案中添加規定'Group_ID IS NOT NULL'的子句。在這個條款中,我不明白爲什麼它不起作用。除了組ID以外(其中group_ID在兩行中都不爲空)插入一行幷包含所有相同的數據並刪除舊行與將舊行的組標識更新爲新行的組標識具有相同的淨效果。 – GarethD

+0

只有在存在具有不同「搜索」和「顯示」列以及同一個「user_id」,「字段」和「group_id」列的行時,它纔會更新。我的問題措辭不佳(我注意到我已經完全忽略了更新內容),但我認爲我越來越接近了! – schme

0

刪除瀏覽GROUP_ID其中GROUP_ID = 'NULL'

+0

這是不正確的,因爲NULL不是一個值。 'WHERE group_id IS NOT NULL'將是正確的,但我不知道這裏是否有解決方案,因爲我還沒有讀過這個問題。 – deed02392

0

你的問題是不太好理解,所以我不知道這是你想要的!

DELETE FROM Views WHERE # delete from the table views 
    group_id IS NOT NULL AND # first condition delete only rows with not null group_id 
    (SELECT count(*) as tot FROM Views GROUP BY group_id) = 1 # second condition count the difference in group id 

如果這不是你想要的,請更新你的問題更多細節...