MYSQL SELECT到DELETE指定两次

时间:2018-12-02 15:27:17

标签: mysql sql

将SELECT更改为DELETE时出现问题:

DELETE
FROM mitarbeiter
WHERE mitarbeiter.pers_nr=
(SELECT mitarbeiter.pers_nr
FROM mitarbeiter
LEFT JOIN kunde ON kunde.betreuer=mitarbeiter.pers_nr
group by mitarbeiter.pers_nr
order by count(*)
limit 1);

错误提示...

Table 'mitarbeiter' is specified twice, both as a target for 'DELETE' and as a separate source for data

我该如何更改?

4 个答案:

答案 0 :(得分:1)

您可以使用JOIN替换逻辑:

DELETE m
    FROM mitarbeiter m JOIN
         (SELECT m2.pers_nr
          FROM mitarbeiter m2 LEFT JOIN
               kunde k
               ON k.betreuer = m2.pers_nr 
          GROUP BY m2.pers_nr 
          ORDER BY COUNT(*) 
          LIMIT 1
         ) m2
         ON m.pers_nr = m2.pers_nr;

也就是说,逻辑可能可以简化,但这很奇怪。您将COUNT(*)LEFT JOIN一起使用,因此即使第二张表中的不匹配项也得到了1。知道您的意图(包括示例数据和期望的结果)将有助于其他人找出是否另一种方法会更好。

答案 1 :(得分:1)

您可以尝试在基于联接的表和表中将其用作同一子查询的别名,而不是在哪里和子查询

DELETE m.*
FROM mitarbeiter m
INNER JOIN (
    SELECT mitarbeiter.pers_nr
    FROM mitarbeiter
    LEFT JOIN kunde ON kunde.betreuer=mitarbeiter.pers_nr
    group by mitarbeiter.pers_nr
    order by count(*)
    limit 1
) t ON t.pers_nr = m.pers_nr

答案 2 :(得分:0)

您可以尝试的另一种解决方法是将子查询保存在临时表中,然后从该表中调用行。

DROP TABLE IF EXISTS tempTable;

CREATE TEMPORARY TABLE tempTable
SELECT mitarbeiter.pers_nr 
FROM mitarbeiter 
LEFT JOIN kunde 
ON kunde.betreuer=mitarbeiter.pers_nr 
GROUP BY mitarbeiter.pers_nr 
ORDER BY COUNT(*)
LIMIT 1;

DELETE FROM mitarbeiter 
WHERE mitarbeiter.pers_nr 
IN (
    SELECT * FROM tempTable
);

DROP TABLE tempTable;  -- cleanup

警告:与在其他解决方案中使用JOIN相比,这可能需要更长的时间和/或更大的空间。

答案 3 :(得分:0)

欢迎堆栈溢出!这是否有助于您指出正确的方向?

我经常发现当我使用Common Table Expressions

时,我的弱智大脑更容易看到结果可视化

请注意,版本8.0之前的MySQL doesn't support the WITH clause

CREATE TABLE IF NOT EXISTS mitarbeiter (
  pers_nr varchar(10),
  PRIMARY KEY (pers_nr)
) DEFAULT CHARSET=utf8;
INSERT INTO mitarbeiter (pers_nr) VALUES
('Scum'),
('Worker'),
('Manager'),
('President');

CREATE TABLE IF NOT EXISTS kunde (
  kunde_id int(3) NOT NULL,
  betreuer varchar(10) NOT NULL,
  PRIMARY KEY (kunde_id)  
) DEFAULT CHARSET=utf8;

INSERT INTO kunde (kunde_id, betreuer) VALUES
(1, 'Scum'),
(2, 'Worker'),
(3, 'Worker'),
(4, 'Manager'),
(5, 'Manager'),
(6, 'Manager'),
(7, 'President'),
(8, 'President'),
(9, 'President'),
(10, 'President');

WITH s1
AS
(SELECT betreuer
      , count(1) AS kunde_count_by_pers_nr -- JJAUSSI: find the kunde count by pers_nr
  FROM kunde
 GROUP BY betreuer
  ),
s2
AS
(SELECT MIN(kunde_count_by_pers_nr) AS kunde_count_by_pers_nr_min -- JJAUSSI: find the lowest kunde_count
  FROM s1),
s3
AS
(SELECT s1.betreuer
  FROM s1 INNER JOIN s2
    ON s1.kunde_count_by_pers_nr = s2.kunde_count_by_pers_nr_min -- JJAUSSI: Retrieve all the betreuer values with the lowest kunde_count
)
SELECT * -- JJAUSSI: Test this result and see if it contains the records you expect to delete
  FROM s3;
--DELETE -- JJAUSSI: Once you are confident in the results from s3, this DELETE can work
--  FROM mitarbeiter
-- WHERE pers_nr IN (SELECT betreuer
--                   FROM s3);

SELECT * -- JJAUSSI: Check for the desired results (we successfully got rid of 'Scum'!)
  FROM mitarbeiter;