【问题标题】:Create a table with duplicate values, and use a CTE (Common Table Expression )to delete those duplicate values创建具有重复值的表,并使用 CTE(通用表表达式)删除这些重复值
【发布时间】:2017-06-23 22:50:43
【问题描述】:

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

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

【问题讨论】:

  • CTE 不会删除任何内容。我也不明白这个问题。创建具有重复值的表很容易:create table tbl as select 1 col1 from dual union all select 1 from dual 创建一个表 tbl,其中包含一列 col1 和两行,该列中的值均为 1。
  • 这就像一个问题片段。它有更多的东西吗?
  • 您使用的是 Oracle 还是 SQL-Server?
  • 看起来类似于:stackoverflow.com/questions/44730226/…。不确定是否需要 CTE,但我怀疑您可以用 CTE 替换子查询。

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


【解决方案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 之外的所有记录)。

【讨论】:

  • 感谢您的清晰解释。请您帮助我如何为初学者学习sql。你有什么链接可以跟进@JohnLBevan 先生
  • 感谢您的回复。看视频怎么样?我在youtube上看过,但答案不同。将有一系列流畅的视频,清晰易懂。
  • @Randy;当然;使用最适合您的方法。我自己不熟悉任何 SQL Server 教程视频系列,但我确信那里有一些;最终浏览,尝试并确定它们是否适合您/如果您觉得自己正在进步。如果是,请坚持下去,如果不是,请浏览其他内容。
【解决方案2】:

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 伪列来匹配要删除的行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    相关资源
    最近更新 更多