Pregunta

Básicamente, creé algunas mesas para jugar: tengo dos mesas principales y una mesa de unión Muchos-Muchos. Aquí está el DDL: (Estoy usando HSQLDB)

CREATE TABLE PERSON
(
    PERSON_ID INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, 
    NAME VARCHAR(50), MAIN_PERSON_ID INTEGER
)

CREATE TABLE JOB
(
    JOB_ID INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, 
    NAME VARCHAR(50)
)
CREATE TABLE JOB_PERSON
(
    PERSON_ID INTEGER, 
    JOB_ID INTEGER
)
ALTER TABLE JOB_PERSON ADD 
    CONSTRAINT FK_PERSON_JOB FOREIGN KEY(PERSON_ID) 
    REFERENCES PERSON ON DELETE CASCADE ON UPDATE CASCADE 

ALTER TABLE JOB_PERSON ADD
    CONSTRAINT FK_JOB_PERSON FOREIGN KEY(JOB_ID) 
    REFERENCES JOB ON DELETE CASCADE ON UPDATE CASCADE

ALTER TABLE PERSON ADD
    CONSTRAINT FK_PERSON_PERSON FOREIGN KEY(MAIN_PERSON_ID) 
    REFERENCES PERSON ON DELETE CASCADE ON UPDATE CASCADE

insert into person values(null,'Arthur', null);
insert into person values(null,'James',0);
insert into job values(null, 'Programmer')
insert into job values(null, 'Manager')
insert into job_person values(0,0);
insert into job_person values(0,1);
insert into job_person values(1,1);

Deseo crear una declaración de eliminación que elimine a los huérfanos del TRABAJO (si solo existe una entrada en la tabla de unión para un trabajo específico) basada en la PERSON.PERSON_ID.

En pseudo idioma:

delete from job where job_person.job_id=job.job_id 
AND count(job_person.job_id)=1 AND job_person.person_id=X

Donde X es alguna person_id. He intentado muchas formas diferentes; Creo que es el " COUNT " parte que está causando problemas. Soy un novato en SQL, por lo que cualquier ayuda sería muy apreciada.

¿Fue útil?

Solución

No estoy siguiendo.

No puede eliminar filas JOB que tienen filas JOB_PERSON (incluso una) debido a sus restricciones FK. Por lo tanto, no hay forma de eliminar las filas JOB basadas en las filas PERSON .

Las filas

JOB_PERSON se deben eliminar antes de que se pueda eliminar JOB o PERSON .

Si desea eliminar todas las filas JOB sin JOB_PERSON , entonces una forma es:

DELETE FROM JOB
WHERE JOB_ID NOT IN (
    SELECT JOB_ID
    FROM JOB_PERSON
)

Si desea eliminar todas las filas de JOB_PERSON para una persona en particular y luego todos los huérfanos, hágalo en dos pasos:

DELETE FROM JOB_PERSON
WHERE PERSON_ID = X

DELETE FROM JOB
WHERE JOB_ID NOT IN (
    SELECT JOB_ID
    FROM JOB_PERSON
)

Si desea eliminar solo los huérfanos JOB previamente vinculados a X, deberá mantenerlos en una tabla temporal antes de la primera eliminación.

INSERT INTO TEMP_TABLE
SELECT JOB.JOB_ID
FROM JOB
INNER JOIN JOB_PERSON
    ON JOB_PERSON.JOB_ID = JOB.JOB_ID
WHERE JOB_PERSON.PERSON_ID = X

DELETE FROM PERSON
WHERE PERSON_ID = X

-- YOUR CASCADING DELETE DOES THIS:
/*
DELETE FROM JOB_PERSON
WHERE PERSON_ID = X
*/

-- Now clean up (only) new orphans on the other side
DELETE FROM JOB
WHERE JOB_ID NOT IN (
    SELECT JOB_ID
    FROM JOB_PERSON
)
AND JOB_ID IN (
    SELECT JOB_ID
    FROM TEMP_TABLE
)

Otros consejos

Esto eliminará de su tabla las entradas de JOB que no tienen entrada en la tabla JOB_PERSON (Orpheans).

DELETE FROM JOB
WHERE JOB_ID NOT IN (
    SELECT JOB_ID
    FROM JOB_PERSON
)

No puede eliminar filas que están vinculadas por un extraño en otra tabla ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top