vista - ¿Cómo escribir una instrucción SQL DELETE con una instrucción SELECT en la cláusula WHERE?
una sentencia select sin la cláusula where devuelve (5)
Base de datos: Sybase Advantage 11
En mi búsqueda para normalizar los datos, intento eliminar los resultados que obtengo de esta declaración SELECT
:
SELECT tableA.entitynum
FROM tableA q
INNER JOIN tableB u on (u.qlabel = q.entityrole AND u.fieldnum = q.fieldnum)
WHERE (LENGTH(q.memotext) NOT IN (8,9,10)
OR q.memotext NOT LIKE ''%/%/%'')
AND (u.FldFormat = ''Date'')
;
Esta es la declaración DELETE
que he creado:
DELETE FROM tableA
WHERE (SELECT q.entitynum
FROM tableA q
INNER JOIN tableB u on (u.qlabel = q.entityrole AND u.fieldnum = q.fieldnum)
WHERE (LENGTH(q.memotext) NOT IN (8,9,10)
OR q.memotext NOT LIKE ''%/%/%'')
AND (u.FldFormat = ''Date''))
;
Obtengo continuamente este error cuando intento ejecutar esta declaración:
ERROR IN SCRIPT: poQuery: Error 7200: AQE Error: State = S0000; NativeError = 2124;
[iAnywhere Solutions][Advantage SQL Engine]Invalid operand for operator: = Boolean value
cannot be operated with non-Boolean value.
También probé esta afirmación:
DELETE FROM tableA
INNER JOIN tableB u on (u.qlabel = tableA.entityrole AND u.fieldnum = tableA.fieldnum)
WHERE (LENGTH(q.memotext) NOT IN (8,9,10)
OR tableA.memotext NOT LIKE ''%/%/%'')
AND (u.FldFormat = ''Date'')
;
Lo que resulta en:
ERROR IN SCRIPT: poQuery: Error 7200: AQE Error: State = 42000; NativeError = 2117;
[iAnywhere Solutions][Advantage SQL Engine] Unexpected token: INNER -- Expecting semicolon.
-- Location of error in the SQL statement is: 23 (line: 2 column: 1)
¿Podría alguien ayudarme a construir correctamente una consulta DELETE que dará como resultado que se eliminen los datos adecuados?
¿No deberías tener:
DELETE FROM tableA WHERE entitynum IN (...your select...)
Ahora solo tienes un DONDE sin comparación:
DELETE FROM tableA WHERE (...your select...)
Entonces su consulta final se vería así;
DELETE FROM tableA WHERE entitynum IN (
SELECT tableA.entitynum FROM tableA q
INNER JOIN tableB u on (u.qlabel = q.entityrole AND u.fieldnum = q.fieldnum)
WHERE (LENGTH(q.memotext) NOT IN (8,9,10) OR q.memotext NOT LIKE ''%/%/%'')
AND (u.FldFormat = ''Date'')
)
Ajusté tu segunda consulta para que funcione. Creo que esto es más sencillo que usar una declaración SELECT
anidada como en las otras respuestas.
DELETE q
FROM tableA q
INNER JOIN tableB u on (u.qlabel = q.entityrole AND u.fieldnum = q.fieldnum)
WHERE (LENGTH(q.memotext) NOT IN (8,9,10)
OR q.memotext NOT LIKE ''%/%/%'')
AND (u.FldFormat = ''Date'')
Más detalles aquí:
Cómo eliminar el uso de INNER JOIN con SQL Server?
Debe identificar la clave principal en TableA para eliminar el registro correcto. La clave principal puede ser una sola columna o una combinación de varias columnas que identifica de manera única una fila en la tabla. Si no hay una clave principal, la pseudocolumna ROWID se puede usar como clave principal.
DELETE FROM tableA
WHERE ROWID IN
( SELECT q.ROWID
FROM tableA q
INNER JOIN tableB u on (u.qlabel = q.entityrole AND u.fieldnum = q.fieldnum)
WHERE (LENGTH(q.memotext) NOT IN (8,9,10) OR q.memotext NOT LIKE ''%/%/%'')
AND (u.FldFormat = ''Date''));
Hizo algo así una vez:
CREATE TABLE exclusions(excl VARCHAR(250));
INSERT INTO exclusions(excl)
VALUES
(''%timeline%''),
(''%Placeholders%''),
(''%Stages%''),
(''%master_stage_1205x465%''),
(''%Accessories%''),
(''%chosen-sprite.png''),
(''%WebResource.axd'');
GO
CREATE VIEW ToBeDeleted AS
SELECT * FROM chunks
WHERE chunks.file_id IN
(
SELECT DISTINCT
lf.file_id
FROM LargeFiles lf
WHERE lf.file_id NOT IN
(
SELECT DISTINCT
lf.file_id
FROM LargeFiles lf
LEFT JOIN exclusions e ON(lf.URL LIKE e.excl)
WHERE e.excl IS NULL
)
);
GO
CHECKPOINT
GO
SET NOCOUNT ON;
DECLARE @r INT;
SET @r = 1;
WHILE @r>0
BEGIN
DELETE TOP (10000) FROM ToBeDeleted;
SET @r = @@ROWCOUNT
END
GO
en este escenario:
DELETE FROM tableA
WHERE (SELECT q.entitynum
FROM tableA q
INNER JOIN tableB u on (u.qlabel = q.entityrole AND u.fieldnum = q.fieldnum)
WHERE (LENGTH(q.memotext) NOT IN (8,9,10)
OR q.memotext NOT LIKE ''%/%/%'')
AND (u.FldFormat = ''Date''));
¿No te estás perdiendo la columna con la que quieres comparar? ejemplo:
DELETE FROM tableA
WHERE entitynum in (SELECT q.entitynum
FROM tableA q
INNER JOIN tableB u on (u.qlabel = q.entityrole AND u.fieldnum = q.fieldnum)
WHERE (LENGTH(q.memotext) NOT IN (8,9,10)
OR q.memotext NOT LIKE ''%/%/%'')
AND (u.FldFormat = ''Date''));
Supongo que es esa columna, ya que en su declaración seleccionada está seleccionando de la misma tabla de la que desea eliminar con esa columna.