Как написать инструкцию SQL DELETE с инструкцией SELECT в предложении WHERE?
База данных: Sybase Advantage 11
В моих поисках нормализации данных я пытаюсь удалить результаты, полученные из этого оператора 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')
;
Это оператор DELETE
, с которым я столкнулся:
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'))
;
Я постоянно получаю эту ошибку, когда пытаюсь запустить этот оператор:
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.
Я также пробовал это утверждение:
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')
;
Результат:
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)
Может ли кто-нибудь помочь мне в правильном построении запроса DELETE, который приведет к удалению надлежащих данных?
Ответы
Ответ 1
Вам нужно определить первичный ключ в таблицеA, чтобы удалить правильную запись. Первичным ключом может быть один столбец или комбинация из нескольких столбцов, которые однозначно идентифицируют строку в таблице. Если первичного ключа нет, в качестве первичного ключа может использоваться псевдо-столбец ROWID.
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'));
Ответ 2
Ваш второй запрос DELETE
был почти верным. Обязательно укажите имя таблицы (или псевдоним) между DELETE
и FROM
чтобы указать, из какой таблицы вы удаляете. Это проще, чем использование вложенного SELECT
как в других ответах.
Исправленный запрос (вариант 1: использование полного имени таблицы):
DELETE tableA
FROM tableA
INNER JOIN tableB u on (u.qlabel = tableA.entityrole AND u.fieldnum = tableA.fieldnum)
WHERE (LENGTH(tableA.memotext) NOT IN (8,9,10)
OR tableA.memotext NOT LIKE '%/%/%')
AND (u.FldFormat = 'Date')
Исправленный запрос (вариант 2: использование псевдонима):
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')
Больше примеров здесь:
Как удалить, используя INNER JOIN с SQL Server?
Ответ 3
Разве вы не должны иметь:
DELETE FROM tableA WHERE entitynum IN (...your select...)
Теперь у вас просто есть ГДЕ без сравнения:
DELETE FROM tableA WHERE (...your select...)
Таким образом, ваш последний запрос будет выглядеть так;
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')
)
Ответ 4
в этом случае:
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'));
Вам не хватает столбца, с которым вы хотите сравнить? Пример:
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'));
Я предполагаю, что это столбец, так как в вашем выборе вы выбираете из той же таблицы, которую вы хотите удалить из этого столбца.
Ответ 5
Сделал что-то подобное:
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