根据其中一列查找并更新非重复记录

时间:2017-07-26 06:40:11

标签: sql sql-server tsql group-by

我想查找所有非重复记录并更新其中一列。

实施例

Col_1 | Col_2 | Col_3 | Col_4 | Col_5
A     | AA    | BB    | 1     | 
A     | AB    | BC    | 2     |
A     | AC    | BD    | 3     |
B     | BB    | CC    | 1     |
B     | BB    | CC    | 2     |
C     | CC    | DD    | 1     |

我的查询必须按Col_1分组,我想找出不是基于Col_2和Col3的唯一记录,然后更新Col_5。

基本上输出应该如下,

Col_1 | Col_2 | Col_3 | Col_4 | Col_5
A     | AA    | BB    | 1     | 1
A     | AB    | BC    | 2     | 1
A     | AC    | BD    | 3     | 1
B     | BB    | CC    | 1     | 0
B     | BB    | CC    | 2     | 0
C     | CC    | DD    | 1     | 0

有谁知道如何实现这一目标?这是一个大型数据库,因此性能也是一个关键因素。

谢谢你,

2 个答案:

答案 0 :(得分:0)

有很多方法可以做到这一点。这个解决方案来自我可以访问的postgres,但是我敢打赌它也会在tsql上运行,因为它应该具有通用的语法。

;WITH
cte_1 AS (
    SELECT col_1 FROM some_table GROUP BY col_1 HAVING count(*) > 1
),
cte_2 AS (
    SELECT col_1 FROM some_table GROUP BY col_1, col_2, col_3 HAVING count(*) > 1
),
cte_3 AS (
    SELECT cte_1.col_1 FROM cte_1
    LEFT JOIN cte_2 ON cte_1.col_1 = cte_2.col_1
    WHERE cte_2.col_1 IS NULL
)
UPDATE some_table SET col_5 = 1
FROM cte_3 WHERE cte_3.col_1 = some_table.col_1;

那么,上面发生了什么?

  1. 首先我们构建了三个CTE半表,它们允许我们将逻辑分成更小的部分:

    • cte_1提取可以有多个col2col_3行的行
    • cte_2选择那些具有非唯一col_2col_3
    • 的广告
    • cte_3只会col_1
    • 返回col_2col_3唯一的LEFT JOIN
  2. 使用上一个cte_3结构,我们可以正确更新some_table

  3. 我假设您的表在此处被称为some_table。如果你担心性能问题,你应该在这里提供一些主键,并且最好在col_2col_3上建立索引(独立但如果它们在{{{{{{ 1}}等等。)

    此外,您可能希望将其从 CTE 移至使用临时表格(也可以将其编入索引以提高效率。

    请注意,此查询适用于您的示例但没有真实数据可能只是猜测。我的意思是当你同时拥有(col_1, col_2) =一个独特且非独特的col_1时会发生什么?

    但我相信这是一个很好的开始。

答案 1 :(得分:0)

git reset