Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

delete con inner join

Estas en el tema de delete con inner join en el foro de Mysql en Foros del Web. Buen dia. Sera que me pueden decir por que no me funciona esta instruccion sql? delete from tbllogrosxgrado inner join tbllogros on tbllogrosxgrado.id_logro=tbllogros.id_logro where identificacion='1036606448' ...
  #1 (permalink)  
Antiguo 25/09/2009, 10:50
 
Fecha de Ingreso: mayo-2009
Mensajes: 177
Antigüedad: 14 años, 11 meses
Puntos: 1
Pregunta delete con inner join

Buen dia.

Sera que me pueden decir por que no me funciona esta instruccion sql?

delete from tbllogrosxgrado
inner join tbllogros on tbllogrosxgrado.id_logro=tbllogros.id_logro
where identificacion='1036606448'

ya llevo tiempo usando el inner join, pero es la primera vez que lo empleo en un delete y no me ha querido funcionar.

me dice esto:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'inner join tbllogros on tbllogrosxgrado.id_logro=tbllogros.id_logro where ident' at line 2

Les agradezco de antemano por su atencion.
  #2 (permalink)  
Antiguo 25/09/2009, 16:13
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: delete con inner join

Que yo sepa, mysql no soporta inner join en sentencias delete.
Haz uso de on delete cascade y on update cascade.

saludos
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #3 (permalink)  
Antiguo 25/09/2009, 16:51
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: delete con inner join

En realidad, si se puede usar, según dice el manual de referencia (13.2.1. Sintaxis de DELETE ), por lo que supongo que el problema puede venir de otra parte.
La sentencia que usas es (reescribiendo):
Código sql:
Ver original
  1. DELETE FROM tbllogrosxgrado
  2.             INNER JOIN tbllogros USING(id_logro)
  3. WHERE identificacion='1036606448';

No se ve ningún error. ¿Este es un ejemplo real, o está implementado de otra forma? Por ejemplo, con el valor en una variable...
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #4 (permalink)  
Antiguo 26/09/2009, 21:16
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: delete con inner join

Ni en la versión 5 ni en la 5.1 me ha funcionado. gnzsoloyo en el link que pones no hacen uso en ninguna parte de la sentencia inner join, sino de delete con múltiples tablas. esto se muestra como un error de sintaxis.

Cita:
La parte table_references lista las tablas involucradas en el join. Esta sintaxis se describe en Sección 13.2.7.1, “Sintaxis de JOIN”.

Para la primera sintaxis, sólo los registros coincidentes de las tablas listadas antes de la cláusula FROM se borran. Para la segunda sintaxis, sólo los registros coincidentes de las tablas listadas en la cláusula FROM (antes de la cláusula USING ) se borran. El efecto es que puede borrar registros para varias tablas al mismo tiempo y tienen tablas adicionales que se usan para buscar:

DELETE t1, t2 FROM t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;
O:

DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;
Estos comandos usan las tres tablas al buscar registros a borrar, pero borrar los registros coincidentes sólo para las tablas t1 y t2.

Los ejemplos anteriores muestran inner joins usando el operador coma, pero comandos DELETE de varias tablas pueden usar cualquier tipo de join permitido por comandos SELECT tales como LEFT JOIN.
Aunque diga que permite multiples sentencias join, siempre genera error de sintaxis al tratar de hacerlo como propones.

La forma como me ha funcionado (en parte) es:

Código sql:
Ver original
  1. DELETE tblg,tbl FROM tbllogrosxgrado tblg,tbllogros tbl WHERE tblg.id_logro=tbl.id_logro

El problema es que elimina todos los registros que hayan entre las tablas. si le pongo la condición and identificacion='1036606448';
saca un error de integridad referencial.

Insisto en el uso de on delete cascade

saludos
__________________
Without data, You are another person with an opinion.
W. Edwads Deming

Última edición por huesos52; 27/09/2009 a las 06:44
  #5 (permalink)  
Antiguo 27/09/2009, 07:18
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: delete con inner join

Estoy de acuerdo en que un ON DELETE CASCADE es muchísimo más eficiente. Lo que yo quería destacar es que según el manual de referencia ese DELETE debería funcionar, ya que, también según el manual:
Cita:
Puede especificar múltiples tablas en un comando DELETE para borrar registros de una o más tablas dependiendo de una condición particular en múltiples tablas. Sin embargo, no puede usar ORDER BY o LIMIT en un DELETE de múltiples tablas.

La parte table_references lista las tablas involucradas en el join. Esta sintaxis se describe en Sección 13.2.7.1, “Sintaxis de JOIN”.
y es la sección 13.2.7.1 dice:
Cita:
MySQL soporta las siguientes sintaxis de JOIN para la parte table_references de comandos SELECT y DELETE y UPDATE de múltiples tablas:

table_reference, table_reference
table_reference [INNER | CROSS] JOIN table_reference [join_condition]
table_reference STRAIGHT_JOIN table_reference
table_reference LEFT [OUTER] JOIN table_reference join_condition
table_reference NATURAL [LEFT [OUTER]] JOIN table_reference
{ ON table_reference LEFT OUTER JOIN table_reference
ON conditional_expr }
table_reference RIGHT [OUTER] JOIN table_reference join_condition
table_reference NATURAL [RIGHT [OUTER]] JOIN table_reference
Y además:
Cita:
INNER JOIN y , (coma) son semánticamente equivalentes en la ausencia de una condicicón de join: ambos producen un producto Cartesiano entre las tablas especificadas (esto es, cada registro en la primera tabla se junta con cada registro en la segunda tabla).
Por ello mi duda es que si dicen que debería funcionar, ¿por qué razón ni tu ni él han logrado que esto funcione?

Googleando, he encontrado este caso, en que se muestra la ocurrencia de ese DELETE: http://www.java2s.com/Tutorial/MySQL...TableJoins.htm
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #6 (permalink)  
Antiguo 27/09/2009, 08:12
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: delete con inner join

Si.. el manual es claro y estoy deacurdo que debería funcionar.
A ti te funciona gnzsoloyo?


En el link que acabas de poner funciona, pero ten en cuenta que las tablas no están relacionadas. No existen claves primarias ni foráneas.
__________________
Without data, You are another person with an opinion.
W. Edwads Deming

Última edición por huesos52; 27/09/2009 a las 08:46
  #7 (permalink)  
Antiguo 27/09/2009, 09:24
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: delete con inner join

Bien, finalmente conseguí en una página que tenía ejercicios sobre DELETE en MySQL un script de prueba para el caso, y lo probé.
Funcionó tras unas modificaciones.

El tema pasa por establecer el orden de borrado, y definir específicamente qué tabla es la que se va a borrar, ya que el DELETE puede abarcar todas las tablas, algunas o una sola de las involucradas
El script que usé es este:
Código sql:
Ver original
  1. DROP TABLE IF EXISTS AuthorArticle;
  2. DROP TABLE IF EXISTS Articles;
  3. DROP TABLE IF EXISTS Authors;
  4.  
  5.  
  6.  
  7. CREATE TABLE Articles (
  8.    ArticleID SMALLINT NOT NULL PRIMARY KEY,
  9.    ArticleTitle VARCHAR(60) NOT NULL,
  10.    Copyright YEAR NOT NULL
  11. )
  12. ENGINE=INNODB;
  13.  
  14.  
  15. INSERT INTO Articles VALUES (12786, 'How write a paper', 1934),
  16.                             (13331, 'Publish a paper', 1919),
  17.                             (14356, 'Sell a paper', 1966),
  18.                             (15729, 'Buy a paper', 1932),
  19.                             (16284, 'Conferences', 1996),
  20.                             (17695, 'Journal', 1980),
  21.                             (19264, 'Information', 1992),
  22.                             (19354, 'AI', 1993);
  23.  
  24.  
  25. CREATE TABLE Authors (
  26.    AuthID SMALLINT NOT NULL PRIMARY KEY,
  27.    AuthorFirstName VARCHAR(20),
  28.    AuthorMiddleName VARCHAR(20),
  29.    AuthorLastName VARCHAR(20)
  30. )
  31. ENGINE=INNODB;
  32.  
  33.  
  34. INSERT INTO Authors VALUES (1006, 'Henry', 'S.', 'Thompson'),
  35.                            (1007, 'Jason', 'Carol', 'Oak'),
  36.                            (1008, 'James', NULL, 'Elk'),
  37.                            (1009, 'Tom', 'M', 'Ride'),
  38.                            (1010, 'Jack', 'K', 'Ken'),
  39.                            (1011, 'Mary', 'G.', 'Lee'),
  40.                            (1012, 'Annie', NULL, 'Peng'),
  41.                            (1013, 'Alan', NULL, 'Wang'),
  42.                            (1014, 'Nelson', NULL, 'Yin');
  43.  
  44.  
  45. CREATE TABLE AuthorArticle (
  46.    AuthID SMALLINT NOT NULL,
  47.    ArticleID SMALLINT NOT NULL,
  48.    PRIMARY KEY (AuthID, ArticleID),
  49.    FOREIGN KEY (AuthID) REFERENCES Authors (AuthID),
  50.    FOREIGN KEY (ArticleID) REFERENCES Articles (ArticleID)
  51. )
  52. ENGINE=INNODB;
  53.  
  54.  
  55. INSERT INTO AuthorArticle VALUES (1006, 14356),
  56.                               (1008, 15729),
  57.                               (1009, 12786),
  58.                               (1010, 17695),
  59.                               (1011, 15729),
  60.                               (1012, 19264),
  61.                               (1012, 19354),
  62.                               (1014, 16284);
En este ejemplo existe una dependencia entre la tabla AuthorArticle y las otras dos, por lo cual para eliminar cualquiera de los registros ubicados en Author y Article, primero hay que eliminar el registro donde se vinculan en AuthorArticle.
Para lograrlo no podemos hacer:
Código sql:
Ver original
  1. DELETE  
  2. FROM Authors a INNER JOIN AuthorArticle ab USING(AuthID)
  3.    INNER JOIN Articles b USING(ArticleID)
  4. WHERE AuthorLastName='Elk';
porque eso implicaría que los registros se borren de las tablas en esta secuencia: Authors -> AuthorArticle -> Article , lo que genera un problema de restricción de FK.
Para lograr que se borren, hay que establecer la secuencia de otra forma: AuthorsArticle -> Author -> Article.
Esto sería:
Código sql:
Ver original
  1. DELETE ab, b
  2. FROM Authors a INNER JOIN AuthorArticle ab USING(AuthID)
  3.    INNER JOIN Articles b USING(ArticleID)
  4. WHERE AuthorLastName='Elk';
y luego eliminar el tercer registro en la primera tabla:
Código sql:
Ver original
  1. DELETE a
  2. FROM Authors a;
(todavía no analicé por qué no me deja borrar todos juntos).

En el caso debería funcionar con:
Código sql:
Ver original
  1. DELETE lg
  2. FROM tbllogrosxgrado lxg
  3.             INNER JOIN tbllogros lg USING(id_logro)
  4. WHERE lxg.identificacion='1036606448';
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 12:56.