如何在SQL中根据条件去重并保留特定条件的数据?

新手上路,请多包涵

sql如果有重复数据,怎么根据需要去重,比如no相同,优先保留code为b的

五条数据四条code a 一条code b 其中code b的no和code a重复了,最后应该是四条数据,其中三条code a一条code b

阅读 1.8k
avatarAI BotBETA

在SQL中,如果你需要根据特定条件去重并保留特定条件的记录(如你提到的no相同的情况下优先保留codeb的记录),你可以使用ROW_NUMBER()窗口函数或者RANK()窗口函数结合OVER()子句来实现。这里,使用ROW_NUMBER()可能更合适,因为它能为每个分组内的行分配一个唯一的序号,基于你指定的排序顺序。

下面是一个具体的SQL示例,假设你的表名为your_table,它包含nocode两列:

WITH RankedData AS (
    SELECT
        *,
        ROW_NUMBER() OVER(PARTITION BY no ORDER BY CASE WHEN code = 'b' THEN 1 ELSE 2 END, code) AS rn
    FROM
        your_table
)
SELECT
    no,
    code
FROM
    RankedData
WHERE
    rn = 1;

解释

  1. CTE(公用表表达式): 这里使用了一个CTE(WITH RankedData AS (...))来首先处理原始数据。CTE是SQL中的一种临时结果集,它在查询执行期间存在。
  2. ROW_NUMBER(): ROW_NUMBER()函数用于为分区内的每一行分配一个唯一的序号。PARTITION BY no表示我们按照no列的值将数据分组,即每个no值对应一组数据。ORDER BY CASE WHEN code = 'b' THEN 1 ELSE 2 END, code表示在每个分组内,我们首先按照code是否为b进行排序(b排在前面),如果code相同,则按code本身的值排序(这里主要是为了保证排序的稳定性,虽然在这个场景下可能不需要)。
  3. 选择: 最后,从CTE中选择nocode列,但只选择那些rn = 1的行,即每个no分组中序号为1的行,也就是根据我们的排序规则,首先被排序出来的行(即codeb的行,如果存在的话)。

这样,你就可以根据no去重,并在每个no分组中优先保留codeb的记录(如果存在),否则保留其他code的记录。

2 个回答

按照no分组,然后组内排序。存在code a和code b,使code b为组内第一条。取每个分组的第一条

新手上路,请多包涵

SELECT no,code FROM(
SELECT no,code,ROW_NUMBER()OVER(PARTITION BY no ORDER BY code desc) rn
FROM table)a WHERE rn = 1;

推荐问题
宣传栏