使用tsql,是否可以使用唯一的数字标记/分组重复项?

时间:2016-07-01 12:23:22

标签: tsql

在表格中查找重复项是相当容易的,但我正在寻找一种方法来使用唯一标识符对这些重复项进行分组。例如 -

表 -

Id    Col1  Col2   Col3
1     A     A2     B3
2     B     A2     B3
3     C     A22    B33
4     D     A22    B33

输出应为 -

Col2   Col3   UniqueId 
A2     B3     1
A22    B33    2

此SQL将运行超过一百万行。我想知道是否有可能在没有分组的情况下这样做(除非分组是最有效的方式)

3 个答案:

答案 0 :(得分:1)

您可以使用ROW_NUMBER()这样的内容

测试数据

CREATE TABLE #TestData (ID int, Col1 varchar(1), Col2 varchar(3), Col3 varchar(3))
INSERT INTO #TestData (ID, Col1, Col2, Col3)
VALUES
 (1,'A','A2','B3')
,(2,'B','A2','B3')
,(3,'C','A22','B33')
,(4,'D','A22','B33')

查询

SELECT Col2, Col3, UniqueID FROM
    (SELECT ROW_NUMBER() 
        OVER (ORDER BY Col2, Col3) AS UniqueID, 
        Col2, Col3 
    FROM #TestData GROUP BY Col2, Col3) AS EMP

结果

Col2    Col3    UniqueID
A2      B3      1
A22     B33     2

答案 1 :(得分:0)

如何使用HASH。 (非常类似于我前几天发布的答案)

Declare @Table table (id int,Col1 varchar(25),Col2 varchar(25),Col3 varchar(25))
Insert into @Table values
(1,'A','A2','B3'),
(2,'B','A2','B3'),
(3,'C','A22','B33'),
(4,'D','A22','B33')

Select Distinct Col2,Col3,UniqueID=abs(cast(HashBytes('MD5', Col2+Col3) as int)) 
 From @Table

返回

Col2    Col3    UniqueID
A2      B3      768457807
A22     B33     915487006

答案 2 :(得分:0)

使用Identity列和SQL Analytics函数LAG从上一行获取值,只是另一种解决问题的方法(不使用Distinct或Group By )。因此,这不适用于2012年以下的SQL Server版本。

效果:我不知道这会更快。如果您可以描述数据流,表格输入/更新频率和使用模式,我们可以测量和比较,甚至可能提出其他(更好的)替代方案。

假设:Col2 + Col3 = 输出数据表中的唯一。 ID列可以转换为源表上的Identity列(或PK列)(=下面的@Temp_Tbl)。并且输出中的Uniq_ID列不必是Serial(IF因此只需对Select stmt进行一次小调整)

工作原理: 经过查询的块X根据Col2和Col3的顺序获得Col2和Col3的先前值,以获得2个派生列Col2_Prev和Col3_Prev。然后,我们使用这些列通过在where子句中使用它们来消除重复项。

DECLARE @Temp_Tbl TABLE (ID INT IDENTITY(1,1) , Col1 VARCHAR(5), Col2 VARCHAR(5),Col3 VARCHAR(5))

INSERT INTO @Temp_Tbl ( Col1 , Col2, Col3 ) VALUES
('A','A2','B3')     ,
('B','A2','B3')     ,
('C','A22','B33')   ,
('D','A22','B33')   ,
('E','A222','B333') ,
('F','A222','B333') ,
('B1','A2','B3')

 SELECT
         X.ID as Uniq_ID
        ,X.Col1 
        ,X.Col2 
        ,X.Col3 
    --  ,X.Col2_Prev  -- Uncomment For Troubleshooting
    --  ,X.Col3_Prev  -- Uncomment For Troubleshooting
 FROM 
         (
            SELECT  A.*     , 
                    Lag(A.Col2, 1, 0) OVER (ORDER BY A.Col2,A.Col3) as  Col2_Prev ,  -- Get Value for Col2 from Previous Row
                    Lag(A.Col3, 1, 0) OVER (ORDER BY A.Col2,A.Col3) as  Col3_Prev    -- Get Value for Col3 from Previous Row
            From @Temp_Tbl A
         ) X
 WHERE X.Col2 <> X.Col2_Prev AND 
       X.Col3 <> X.Col3_Prev

<强>结果:

Uniq_ID Col1 Col2   Col3
1       A    A2     B3
3       C    A22    B33
5       E    A222   B333