我有一张表TPAIE,2条信息:
通常,对于一个约会,我必须有一个受益人(我支付一次约会的人)。然而,碰巧我有几行具有相同的受益人和相同的日期
COUNTING NUMBEN PERPAI
9 75005100 01/08/13
9 75005109 01/08/13
我怎样才能删除所有这些线路,但每个线路的受益人和特定日期都有?
注意:我发现了类似的东西,但如果我只有一个标识符就可以了
delete from tpaie where numben not in
(select min(numben) from tpaie group by numben, perpai);
注意2:我发现这个sql可以删除多次存在的所有行:我只是说'不要删除第一行'。在某个地方有一个rownum?
delete from tpaie a
where (numben, perpai) in (
select numben, perpai from tpaie b where b.rowid <> a.rowid)
答案 0 :(得分:2)
第二次尝试,你离目标很近。您只需要了解rowid
是唯一物理表行标识符的保留字。查看documentation了解详情。
查询:
delete tpaie
where rowid not in (
select distinct
( first_value(rowid) over (
partition by numben, perpai order by rowid
)
) first_row_id
from
tpaie
)
您可以在this SQLFiddle中看到完整的测试。
<强>更新强>
@mlwacosmos找到了一个性能更好的变种。当然,原始答案中的not in
不是一个好习惯。所以我添加了他的变体来回答以供将来参考:
delete from tpaie a
where
rowid not in (
select distinct
( first_value(rowid)
over (partition by numben, perpai order by rowid)
) first_row_id
from
tpaie b
where
a.numben = b.numben
and
a.perpai = b.perpai
)
and
(numben, perpai) in ( select numben, perpai
from tpaie b
where b.rowid <> a.rowid
)
但是此解决方案再次涉及not in
,因此将in
函数用于另一个分析排名可能会更好:
delete from tpaie a
where
rowid in (
select row_id
from (
select
rowid row_id,
( dense_rank() over ( -- enumerate rows
partition by numben, perpai order by rowid
)
) row_rank
from
tpaie
)
where
row_rank > 1 -- eliminate rows ranked first
)
答案 1 :(得分:0)
使用DISTINCT创建一个临时表,每个日期只获得一个条目,每个日期,删除主表中的所有条目,并使用临时表重新加载它,如:
SELECT DISTINCT numben, perpai
INTO #temp
FROM tpaie
DELETE FROM tpaie
INSERT INTO tpaie
SELECT * FROM #temp
编辑:
对于特定日期,请尝试:
SELECT DISTINCT numben, perpai
INTO #temp
FROM tpaie
WHERE perpai = '01/08/13'
DELETE FROM tpaie
WHERE perpai = '01/08/13'
INSERT INTO tpaie
SELECT * FROM #temp