当前位置: 首页 > 面试题库 >

仅在SQL的列中选择重复值的第一行

微生耘豪
2023-03-14
问题内容

我有表,其中有一列可能在突发中具有相同的值。像这样:

+----+---------+
| id |   Col1  | 
+----+---------+
| 1  | 6050000 |
+----+---------+
| 2  | 6050000 |
+----+---------+
| 3  | 6050000 |
+----+---------+
| 4  | 6060000 |
+----+---------+
| 5  | 6060000 |
+----+---------+
| 6  | 6060000 |
+----+---------+
| 7  | 6060000 |
+----+---------+
| 8  | 6060000 |
+----+---------+
| 9  | 6050000 |
+----+---------+
| 10 | 6000000 |
+----+---------+
| 11 | 6000000 |
+----+---------+

现在,我要修剪Col1重复值的行,并仅选择第一个出现的行。
对于上表,结果应为:

+----+---------+
| id |   Col1  | 
+----+---------+
| 1  | 6050000 |
+----+---------+
| 4  | 6060000 |
+----+---------+
| 9  | 6050000 |
+----+---------+
| 10 | 6000000 |
+----+---------+

如何在SQL中执行此操作?
请注意,仅应删除突发行,并且可以在非突发行中重复值! id=1id=9在样本结果中重复。

编辑:
我用这个实现了它:

select id,col1 from data as d1
where not exists (
    Select id from data as d2
    where d2.id=d1.id-1 and d1.col1=d2.col1 order by id limit 1)

但这仅在ID为顺序的时才有效。id(已删除的ID)之间有间隔,查询中断。我怎样才能解决这个问题?


问题答案:

您可以使用EXISTS半联接来识别候选者:

选择所需的行:

SELECT * FROM tbl t
WHERE  NOT EXISTS (
    SELECT *
    FROM   tbl
    WHERE  col1 = t.col1
    AND    id = t.id - 1
    )
ORDER  BY id;

摆脱不必要的行:

DELETE FROM tbl AS t
-- SELECT * FROM tbl t  -- check first?
WHERE EXISTS (
    SELECT *
    FROM   tbl
    WHERE  col1 = t.col1
    AND    id   = t.id - 1
    );

这有效地删除了每一行,其中的前一行在中具有相同的值col1,从而达到了您设定的目标:每个突发只有第一行幸存。

我留下了评论后的SELECT声明,因为您在执行契约之前应 始终 检查将要删除的内容。

非顺序ID的解决方案

如果您的RDBMS支持CTE和窗口功能(例如PostgreSQL,Oracle,SQL
Server等,但 支持v3.25之前的SQLite
,MS Access或v8.0.1之前的MySQL
),则有一种简便的方法:

WITH cte AS (
    SELECT *, row_number() OVER (ORDER BY id) AS rn
    FROM   tbl
    )
SELECT id, col1
FROM   cte c
WHERE  NOT EXISTS (
    SELECT *
    FROM   cte
    WHERE  col1 = c.col1
    AND    rn   = c.rn - 1
    )
ORDER  BY id;

没有这些细节的 另一种工作方式(应该为您工作):

SELECT id, col1
FROM   tbl t
WHERE  (
    SELECT col1 = t.col1
    FROM   tbl
    WHERE  id < t.id
    ORDER  BY id DESC
    LIMIT  1) IS NOT TRUE
ORDER  BY id;


 类似资料:
  • 问题内容: 想要改善这篇文章吗? 提供此问题的详细答案,包括引文和为什么答案正确的解释。答案不够详细的答案可能会被编辑或删除。 这个问题已经在这里有了答案 : 检索每个组中的最后一个记录-MySQL (27个答案) 去年关闭。 我有此表用于文档(此处为简化版): 如何为每个ID选择一行,而仅选择最大转速? 根据上述数据,结果应包含两行:和。我正在使用 MySQL 。 目前,我在循环中使用检查来检测

  • 我有一个表格结构 如何使用条件?我尝试使用这个,但结果是

  • 我在从下拉列表中获取值时遇到问题。我的结构如下: 我正在创建一个下拉列表,如下所示: 例如,如果我将"3"放入"testme.pos"并选择"Jam",但是模型"testme"附带以下示例结果: 我想看到的是: 任何帮助都会很好。我创建了一个plnkr:选择帮助

  • 问题内容: 这是从单个表中进行的简单选择。目的是选择四个随机乘积,从x个类别的每一个类别中选择一个,并具有几个“ where”限制。我已经试过了: 这种类型的作品,但始终会返回任何给定类别的相同产品。我想更改显示的产品,同时仍然只显示任何给定类别的单个产品。 我也尝试过: 我在想,也许它需要两个选择-第一个选择一个随机的4个类别,第二个选择从每个类别中选择一个随机行,但是a。不知道该怎么做,以及b

  • 问题内容: 假设我们在Django中有一个定义如下的模型: 名称字段不是唯一的,因此可以具有重复的值。我需要完成以下任务:从模型中选择具有至少一个name字段重复值的所有行。 我知道如何使用普通的SQL来做到这一点(可能不是最好的解决方案): 因此,可以使用django ORM选择它吗?还是更好的SQL解决方案? 问题答案: 尝试: 这与使用Django所获得的效果非常接近。问题在于这将返回一个w

  • 我刚开始学习SQL。我正在使用Oracle数据库。 表emp中包含empno、ename、job、mgr、hiredate、sal、comm、deptno列。 我想从ename列中获取每个deptno的第一条记录,ename必须按asc排序。 以下SQL工作: 我想优化它,所以我不需要重写它,如果我添加一些记录到deptno列。 我用distinct-like进行了尝试