567 votos

Error de Mysql 1093 - No se puede especificar la tabla de objetivos para la actualización en la cláusula FROM

Tengo una mesa story_category en mi base de datos con entradas corruptas. La siguiente consulta devuelve las entradas corruptas:

SELECT * FROM  story_category WHERE category_id NOT IN (
SELECT DISTINCT category.id FROM category INNER JOIN 
       story_category ON category_id=category.id);

Traté de borrarlas excluyendo:

DELETE FROM  story_category WHERE category_id NOT IN (
SELECT DISTINCT category.id FROM category 
       INNER JOIN story_category ON category_id=category.id);

pero tengo el siguiente error:

1093 - No se puede especificar la tabla de objetivos 'story_category' para la actualización en la cláusula FROM

¿Cómo puedo superar esto?

693voto

Cheekysoft Puntos 16532

Actualización: Esta respuesta cubre la clasificación general de errores. Para una respuesta más específica acerca de cómo manejar mejor la consulta exacta de la OP, por favor vea La respuesta de DanDarc

En MySQL, no puedes modificar la misma tabla que usas en la parte de SELECT.
Este comportamiento está documentado en: http://dev.mysql.com/doc/refman/5.6/en/update.html

Deberá dejar de utilizar la subconsulta anidada y ejecutar la operación en dos partes, o alternativamente utilizar una cláusula de "dónde" simple.

A continuación, el barón Schwartz, publicado en Nabble :

Sin embargo, puedes hacer actualizaciones de múltiples tablas como esto:

UPDATE tbl AS a
  INNER JOIN tbl AS b ON ....
  SET a.col = b.col

Si necesitas absolutamente la subconsulta, hay una solución alternativa, pero es feo por varias razones, incluyendo el rendimiento:

UPDATE tbl SET col = (
  SELECT ... FROM (SELECT.... FROM) AS x);

La subconsulta anidada en la cláusula FROM crea una temporalidad implícita mesa, así que no cuenta como la misma mesa que estás actualizando.

287voto

Ekonoval Puntos 392

NexusRex siempre y cuando muy buena solución para borrar con la unión de la misma mesa.

Si haces esto:

DELETE FROM story_category
WHERE category_id NOT IN (
        SELECT DISTINCT category.id AS cid FROM category 
        INNER JOIN story_category ON category_id=category.id
)

vas a cometer un error.

Pero si envuelves la condición en una selección más

DELETE FROM story_category
WHERE category_id NOT IN (
    SELECT cid FROM (
        SELECT DISTINCT category.id AS cid FROM category 
        INNER JOIN story_category ON category_id=category.id
    ) AS c
)

¡haría lo correcto!

92voto

Pratik Khadloya Puntos 3481

Recientemente tuve que actualizar los registros en la misma tabla que hice como abajo:

UPDATE skills AS s, (SELECT id  FROM skills WHERE type = 'Programming') AS p
SET s.type = 'Development' 
WHERE s.id = p.id;

34voto

NexusRex Puntos 690
DELETE FROM story_category
WHERE category_id NOT IN (
    SELECT cid FROM (
        SELECT DISTINCT category.id AS cid FROM category INNER JOIN story_category ON category_id=category.id
    ) AS c
)

13voto

sactiw Puntos 7717

Esto es lo que hice para actualizar el valor de una columna de prioridad en 1 si es >=1 en una tabla y en su cláusula WHERE utilizando una subconsulta en la misma tabla para asegurarme de que al menos una fila contiene prioridad=1 (porque esa era la condición que debía comprobarse al realizar la actualización):

UPDATE My_Table
SET Priority=Priority + 1
WHERE Priority >= 1
AND (SELECT TRUE FROM (SELECT * FROM My_Table WHERE Priority=1 LIMIT 1) as t);

Sé que es un poco feo pero funciona bien.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X