2015-10-14 62 views
0

我有一個問題,我正在過濾一堆不同的值。這張桌子上有大約30個不同的過濾器,因爲我仍然是MySQL的新手,我在stored procedure中執行了多個DELETE查詢,從臨時表中進行過濾。這個例子只會顯示我遇到問題的過濾器,這是一個DELETE FROM table WHERE value IN()查詢。DELETE FROM X WHERE IN(..)不刪除行

這裏的一個測試Schisma:

CREATE TABLE accounts (
    user_id INT(11) NOT NULL AUTO_INCREMENT, 
    name VARCHAR(40) NOT NULL, 
    PRIMARY KEY(user_id) 
); 

CREATE TABLE blocked (
    user_id INT(11) NOT NULL, 
    other_id INT(11) NOT NULL, 
); 

INSERT INTO accounts (name) VALUES ('Chris'), ('Andy'); 
INSERT INTO blocked (user_id, other_id) VALUES (1, 2); 

的查詢創建兩個表:含有兩行的帳目表,並含有一個行,其中user_id 1具有user_id 2阻止阻塞表。

這裏是造成了我們一些問題的查詢(請注意查詢其實比顯示的更復雜,但DELETE查詢是100%相同,這個問題通過提供的測試例子仍然存在):

BEGIN 
    #user_in input is a int(11) value bassed in the CALL FUNCTION(ID). 

    CREATE TEMPORARY TABLE IF NOT EXISTS filtered AS (SELECT * FROM accounts); 

    DELETE FROM filtered WHERE user_id IN (SELECT other_id FROM blocked WHERE blocked.user_id = user_in); 

    SELECT * FROM filtered; 
END 

該查詢應刪除user_id字段爲2的行,如阻止表中唯一的行爲(1, 2)

運行直接提供USER_ID SELECT查詢返回,而不只是一個的2

SELECT other_id FROM blocked WHERE blocked.other_id = 2; 

然而,存儲過程返回兩行中other_id。爲什麼?

注:以上查詢是要表明什麼時返回查詢SELECT other_id FROM blocked WHERE blocked.user_id = user_in,另一個例子是SELECT other_id FROM blocked WHERE blocked.user_id = 1授予user_in設置爲1,這兩個查詢將返回一組的(2)這將使刪除查詢的樣子DELETE FROM filtered WHERE user_id IN (2)。無論出於何種原因,這都行不通。

+0

「我在存儲過程中完成」...因爲...? – Strawberry

+0

@Strawberry'因爲我仍然是MySQL的新手,所以我在存儲過程中完成了這個工作,就像'這個表上有大約30個不同的過濾器一樣',存儲過程實際上略長於250行。 SELECT查詢獲得相同結果的複雜度遠高於我的水平。 – Hobbyist

+0

我想我不明白爲什麼你需要過濾表。 – Strawberry

回答

1

的這裏的問題是有這樣的說法:

DELETE FROM filtered WHERE user_id IN (SELECT other_id FROM blocked WHERE blocked.other_id = user_id); 

嘗試將其更改爲這樣:

DELETE FROM filtered WHERE user_id 
IN (SELECT other_id FROM blocked); 

原因是該blocked表既有other_iduser_id列。因此,在您嘗試加入filtered表的位置時,實際上僅比較blocked表中的other_iduser_id列。哪些不相等。所以不會發生刪除。

+0

另外一個優化整個事情的方法是在選擇阻止的ID內添加「DISTINCT」,以便該語句顯示就像'DELETE FROM filtered WHERE user_id IN(SELECT DISTINCT other_id FROM blocked);' – KuKeC

+0

Tom,這個問題就是如果'user_id'1 user_id 2被阻塞了。然後'2'將在'other_id'字段中。因此,即使user_id 3沒有阻止user_id 2,他仍然會被過濾掉,因爲user_id 1會。這是'WHERE'聲明發揮作用的地方。 – Hobbyist

+0

@Tom Mac,我解決了我的問題,其中'user_id'應該是'user_in'。我很抱歉,請再看一下'DELETE'查詢以查看更改。目標是僅返回提供的user_id的阻止字段的值。 – Hobbyist

2

爲了得到一個簡單的選擇的用戶使用一個查詢

SELECT * FROM accounts WHERE accounts.user_id NOT IN (SELECT distinct blocked.other_id from blocked) 

要使用一個單一的選擇做到這一點,但不刪除從臨時表使用一個查詢行:

BEGIN 
    CREATE TEMPORARY TABLE IF NOT EXISTS filtered AS (SELECT * FROM accounts WHERE accounts.user_id NOT IN (SELECT distinct blocked.other_id from blocked)); 
    SELECT * from filtered; 
END 

無需選擇全部在臨時表中,然後刪除特定的行。

希望它可以幫助

編輯:

心中已經閱讀問題,仍然有點困惑你的問題。但我檢查了這個解決方案,它完美的工作,所以我不明白這是什麼問題。在你的程序中,你有

DELETE FROM filtered WHERE user_id IN (SELECT other_id FROM blocked WHERE blocked.user_id = user_in); 

之後,你說

SELECT other_id FROM blocked WHERE blocked.other_id = 2; 

,我可以說,blocked.other_idblocked.user_id是兩個不同的列。

沒有不敬,但業餘錯誤混列。 :)

+0

請閱讀這個問題,「這張表上有大約30個不同的過濾器」,所以發出一個SELECT語句不會削減它。我擁有的商店程序超過250行,我正在尋求有關單個過濾器問題的幫助。 – Hobbyist

+0

糟糕!我改變了'DELETE'查詢以反映'user_in'字段,但忘記將返回的查詢改爲適當的例子!無論哪種方式,查詢結果仍然是一個包含'(2)'的集合,它不會從我的表中刪除。 '(where user_id = 2)'在這個事件中。也許這是一個MySQL版本的錯誤。我會嘗試再次更新並執行查詢。 – Hobbyist

+0

我添加了一個解釋,爲什麼我在該問題中使用了SELECT查詢。順便說一句。 :)。 – Hobbyist

相關問題