MYSQL SELECT для удаления указан дважды - PullRequest
0 голосов
/ 02 декабря 2018

При переключении 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 голосов
/ 02 декабря 2018

Добро пожаловать в переполнение стека!Помогает ли это вам направить вас в правильном направлении?

Я часто нахожу, что визуализация результатов становится легче для моего слабого мозга, когда я использую Общие табличные выражения

Обратите внимание, что MySQL до версии 8.0 не поддерживает предложение WITH

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;
0 голосов
/ 02 декабря 2018

Вместо where и подзапроса вы можете использовать usin на основе объединения и таблицу в качестве псевдонима для того же подзапроса

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
0 голосов
/ 02 декабря 2018

Еще один обходной путь, который вы можете попробовать - сохранить подзапрос во временной таблице, а затем вызвать строки из этой таблицы.

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, как в других решениях.

0 голосов
/ 02 декабря 2018

Вы можете заменить логику на 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. Знание ваших намерений - с примерами данных и желаемыми результатами - поможет другим понять, сработает ли другой подход.лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...