39

数据库:的Sybase优势11如何在WHERE子句中用SELECT语句编写SQL DELETE语句?

在我的追求,以标准化的数据,我想删除的结果我从这个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查询,将导致正确的数据被删除?

+0

最坏的情况 - 你可以创建一个临时表中,选择到该临时表,做您的加盟删除临时表,然后滴速临时表? –

回答

73

您需要确定TableA中的主键以删除正确的记录。主键可以是唯一标识表格中的一行的单列或多列的组合。如果没有主键,则可以使用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')); 
+0

谢谢亚历克斯的快速反应。 @AlexW我认为你碰到了头部。该表的工作方式是entitynum与许多记录相关,因此它本身不是主键。我没有在Advantage中使用ROWID psuedcolumn的经验。你能否提供解释如何使用这个?再次感谢。 – LuiCami

+0

谢谢@AlexW这个工作非常棒! – LuiCami

9

你不应该有:

DELETE FROM tableA WHERE entitynum IN (...your select...) 

现在你只需要没有比较的WHERE:

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') 
) 
+0

感谢您的回复。它好像当我跑什么,我要删除我结束了远远超过记录原本打算(共4598021,而不是32061)的计数。我完全达到了我的专业水平。你知道这是事实吗?我count语句是这样的:SELECT COUNT(*)FROM表A WHERE entitynum IN(SELECT q.entitynum FROM表A q INNER JOIN tableB的U ON(u.qlabel = q.entityrole AND u.fieldnum = q.fieldnum)WHERE(长度(q.memotext)NOT IN(8,9,10)OR q.memotext NOT LIKE '%/%/%')AND(u.FldFormat = '日期')); – LuiCami

3

在这样的场景:

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'));  

我认为这是该列,因为在您选择的语句中,您从同一张表中选择要从该列中删除的表。

+0

感谢您的回复。看起来好像当我计算我将要删除的内容时,我的记录比最初的记录要多得多(4598021而不是32061)。我完全达到了我的专业水平。你知道这是事实吗?我的计数语句如下所示:SELECT COUNT(*)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) (长度(q.memotext)不在(8,9,10) 或q.memotext NOT LIKE'%/%/ – LuiCami

+0

这个选择给你正确的值来删除? – Andres

+0

如果entityAum在TableA中不唯一(或主键),那么大数目肯定是可能的。例如,可能有若干行的entitynum等于1,但只有其中一个匹配连接条件。但是条件“entitynum IN(SELECT ...)”将返回所有entitynum行等于1 –

1

不喜欢的东西,一旦:

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 
4

我调整你的第二查询,以使其发挥作用。我认为这比使用其他答案中嵌套的SELECT陈述更直接。这里

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') 

更多细节:
How to Delete using INNER JOIN with SQL Server?