2015-10-14 126 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

相关问题