it-swarm.asia

كيفية كتابة عبارة 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 بشكل صحيح سينتج عنه إزالة البيانات المناسبة؟

54
LuiCami

تحتاج إلى تحديد المفتاح الأساسي في 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'));
102
Alex W

استعلام 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؟

19
MarredCheese

لا ينبغي أن يكون لديك:

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

في هذا السيناريو:

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

أفترض أنه هذا العمود نظرًا لأنك في البيان المحدد الذي تختاره من نفس الجدول الذي تريد حذفه من هذا العمود.

4
Andres

فعلت شيئا من هذا القبيل مرة واحدة:

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
1
Matthew Hub