我想要一个SQL语句来删除表中的最新记录。这是我的想法:
delete from daily_statistics
where process_date = (
select max(process_date)
from daily_statistics
);
但似乎有一种方法可以在没有子选择的情况下做到这一点,这可能是低效的。 (效率在我的情况下并不重要,我只是想知道最简单,最易读的编码方式。)
答案 0 :(得分:3)
最可读的方式可能就是你写的。但取决于各种因素,它可能非常浪费。特别是,如果process_date
上没有索引,则可能需要进行2次全表扫描。
编写既简单又高效的内容的困难在于,包含排名或排序的表格的任何视图也不允许修改。
这是使用PL / SQL的另一种方法,在某些情况下可能更有效,但显然不太可读。
DECLARE
CURSOR delete_cur IS
SELECT /*+ FIRST_ROWS(1) */
NULL
FROM daily_statistics
ORDER BY process_date DESC
FOR UPDATE;
trash CHAR(1);
BEGIN
OPEN delete_cur;
FETCH delete_cur INTO trash;
IF delete_cur%FOUND THEN
DELETE FROM daily_statistics WHERE CURRENT OF delete_cur;
END IF;
CLOSE delete_cur;
END;
/
另请注意,如果可能存在多个具有相同process_date
值的行,则可能会从您的语句中产生不同的结果。要使它处理重复项需要更多的复杂性:
DECLARE
CURSOR delete_cur IS
SELECT /*+ FIRST_ROWS(1) */
process_date
FROM daily_statistics
ORDER BY process_date DESC
FOR UPDATE;
del_date DATE;
next_date DATE;
BEGIN
OPEN delete_cur;
FETCH delete_cur INTO del_date;
IF delete_cur%FOUND THEN
DELETE FROM daily_statistics WHERE CURRENT OF delete_cur;
END IF;
LOOP
FETCH delete_cur INTO next_date;
EXIT WHEN delete_cur%NOTFOUND OR next_date <> del_date;
DELETE FROM daily_statistics WHERE CURRENT OF delete_cur;
END LOOP;
CLOSE delete_cur;
END;
/
答案 1 :(得分:3)
我知道有一种更好的方法,我没想到。
delete from daily_statistics
where rowid = (
select max(rowid) keep (dense_rank first order by process_date desc)
from daily_statistics
);
同样,这只会删除一行,即使有多行具有最大值,因此根据您的数据,它可以产生与原始查询不同的结果。