从X WHERE IN(..)删除不删除行

时间:2015-10-14 09:11:05

标签: mysql

我有一个问题,我用一堆不同的值过滤表。这个表上有大约30个不同的过滤器,因为我仍然是MySQL的新手,我在stored procedure执行多个DELETE查询从临时表中进行过滤。此示例仅显示我遇到问题的过滤器,即DELETE FROM table WHERE value 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);

查询创建两个表:包含两行的accounts表,以及包含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)

直接运行SELECT查询提供user_id会返回other_id为2。

SELECT other_id FROM blocked WHERE blocked.other_id = 2;

但是,存储过程返回两行,而不是一行。为什么呢?

注意:以上查询用于显示查询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)。无论出于何种原因,这都行不通。

2 个答案:

答案 0 :(得分: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是两个不同的列。

没有不尊重但业余错误混淆列。 :)

答案 1 :(得分: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表的位置时,您实际上仅比较other_id表中的user_idblocked列。哪些不相等。所以不会发生删除。