创建具有重复值的表,并使用CTE(公用表表达式)删除这些重复值

时间:2017-06-23 22:50:44

标签: sql sql-server oracle sql-server-2008

创建具有重复值的表,并使用CTE(公用表表达式)删除这些重复值。

=> 有人请帮助我如何启动它,因为我真的不明白这个问题。 假设可以选择猜测重复值。

2 个答案:

答案 0 :(得分:1)

对于MS SQL Server,这将起作用:

;with cte as
(
    select *
    , row_number() over (
        partition by [columns], [which], [should], [be], [unique]
        order by [columns], [to], [select], [what's], [kept]
    ) NoOfThisDuplicate
)
delete 
from cte
where NoOfThisDuplicate > 1

SQL Fiddle Demo(根据这个问题:Deleting duplicate row that has earliest date)。

<强>解释

  • 创建CTE
  • 使用我们要删除的表格中的所有行填充
  • 向该输出添加NoOfThiDuplicate
  • 使用此记录的序号填充此值,并将所有记录的组/分区与列[columns], [which], [should], [be], [unique]的值相同。
  • 编号的顺序取决于按列[columns], [to], [select], [what's], [kept]排序时这些记录的排序顺序
  • 我们删除CTE返回的所有记录,除了每组中的第一个(即除NoOfThisDuplicate=1之外的所有记录)。

答案 1 :(得分:0)

Oracle安装程序

CREATE TABLE test_data ( value ) AS
  SELECT LEVEL   FROM DUAL CONNECT BY LEVEL <= 10
UNION ALL
  SELECT 2*LEVEL FROM DUAL CONNECT BY LEVEL <= 5;

查询1

这将选择删除重复项的值:

SELECT DISTINCT *
FROM   test_data

但它不使用CTE。

查询2

因此,我们可以将它放在子查询分解子句中(Oracle文档中使用的名称对应于SQL Server公用表表达式)

WITH unique_values ( value ) AS (
  SELECT DISTINCT *
  FROM   test_data
)
SELECT * FROM unique_values;

查询3

在前面的例子中,子查询因子分解是没有意义的......所以以不同的方式进行:

WITH row_numbers ( value, rn ) AS (
  SELECT value, ROW_NUMBER() OVER ( PARTITION BY value ORDER BY ROWNUM ) AS rn
  FROM   test_data
)
SELECT value
FROM   row_numbers
WHERE  rn = 1;

将选择找到每个值的第一个实例的行。

删除查询

但是这并没有删除行...

DELETE FROM test_data
WHERE  ROWID IN (
  WITH row_numbers ( rid, rn ) AS (
    SELECT ROWID, ROW_NUMBER() OVER ( PARTITION BY value ORDER BY ROWNUM ) AS rn
    FROM   test_data
  )
  SELECT rid
  FROM   row_numbers
  WHERE  rn > 1
);

使用ROWID伪列来匹配要删除的行。