当数据丢失2时,删除行

时间:2014-09-22 18:43:06

标签: mysql sql join sql-delete

我曾经使用连接和" IS NULL"来删除行,就像 this

实施例

人A的类型1是1号。人B有2型的数字2,但也有1型的1号。

查询:

SELECT people.name,
 GROUP_CONCAT(phone_numbers.phone_number) AS "All number",
 GROUP_CONCAT(IF(phone_numbers.type_id = 2, phone_numbers.phone_number, NULL)) AS "Type 2 Numbers" 
FROM people 
LEFT JOIN people_phones USING (people_id) 
LEFT JOIN phone_numbers USING (phone_number) 
GROUP BY people_id;

结果:

+------+------------+----------------+
| name | All number | Type 2 Numbers |
+------+------------+----------------+
| A    | 1          | NULL           |
| B    | 1,2        | 2              |
+------+------------+----------------+

我想删除所有没有类型2号码的人,在这种情况下是人员A.

首先我尝试了usal方式(如果它的一个加入就行了)

尝试:

DELETE people 
FROM people 
LEFT JOIN people_phones USING (people_id) 
LEFT JOIN phone_numbers 
  ON (phone_numbers.phone_number = people_phones.phone_number
      AND phone_numbers.type_id = 2) 
WHERE phone_numbers.phone_number IS NULL;

但这会删除Person' A'和人' B'作为' B'有一个不是2的数字。

如何删除没有2号号码的人?
(真正的例子有更多的连接,更复杂的部分和表中的5个miljon行。)

用于重新创建示例数据的SQL:

CREATE TABLE people (people_id INT NOT NULL AUTO_INCREMENT KEY, name TINYTEXT NOT NULL);
CREATE TABLE phone_numbers (phone_number INT NOT NULL KEY, type_id INT NOT NULL);
CREATE TABLE people_phones (people_id INT NOT NULL, phone_number INT NOT NULL, PRIMARY KEY(people_id, phone_number))

INSERT INTO people VALUES (1,'A'),(2,'B');
INSERT INTO phone_numbers VALUES (1, 1), (2,2);
INSERT INTO people_phones VALUES (1,1), (2,1), (2,2);

1 个答案:

答案 0 :(得分:3)

这是一种方式:

DELETE p
FROM people AS p
WHERE p.people_id NOT IN (SELECT pp.people_id
                          FROM people_phones as pp
                          INNER JOIN phone_numbers as pn
                             ON pp.phone_number = pn.phone_number
                          WHERE pn.type_id = 2);

另一种方式:

DELETE p
FROM people AS p
WHERE NOT EXISTS(SELECT 1 
                 FROM people_phones as pp
                 INNER JOIN phone_numbers as pn
                    ON pp.phone_number = pn.phone_number
                 WHERE pn.type_id = 2
                 AND pp.people_id = p.people_id);

Here is a sqlfiddle带有第二个版本的演示(也是我推荐的那个)。